Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about thenable values #193

Open
Octane opened this issue May 20, 2015 · 4 comments
Open

Question about thenable values #193

Octane opened this issue May 20, 2015 · 4 comments

Comments

@Octane
Copy link
Contributor

Octane commented May 20, 2015

I came across the following problem:

var promise = Promise.resolve({});

promise.then(function (value) {
    value.then = function (onFulfilled) {
        onFulfilled(123);
    };
});

promise.then(function (value) {
    console.log(value); // 123 in Chrome 44, object in Firefox 40
});

This example works differently in Chrome 44 and Firefox 40. Who is wrong?

http://jsbin.com/losuze/1/edit?js,console

@RubaXa
Copy link

RubaXa commented May 20, 2015

👍

@bergus
Copy link

bergus commented May 20, 2015

👍 Chrome is wrong here. Two callbacks on the same promise must never be invoked with different arguments.

A more interesting example would be

var promise = Promise.resolve({});

promise.then(function (value) {
    value.then = function (onFulfilled) {
        onFulfilled(125);
    };
    return promise;
}).then(function (value) {
    console.log(value); // what do they do here?
});

125 would follow the spec, but I think the spec is wrong: https://esdiscuss.org/topic/don-t-test-promise-results-on-their-thenability-multiple-times - see also #179

@briancavalier
Copy link
Member

but I think the spec is wrong

It sure seems that way to me too. IMHO, you shouldn't be able to trick the machinery by turning a promise's fulfillment value into a thenable after fact. FWIW, when.js, bluebird, and rsvp all seem to log an object.

This example works differently in Chrome 44 and Firefox 40

Node 0.12.2 and io.js 2.0.1 native Promise also log 123

@ForbesLindesay
Copy link
Member

(deleted previous comments as I didn't read prior code quite carefully enough)

@Octane's example should definitely always log the object, because the resolution algorithm is applied at the time the promise is created, not when .then is called. This most likely happens as a result of a very old spec that used to suggest that promises could be nested, but would be automatically unwrapped by .then. Firefox is, as far as I can tell, behaving correctly as per the spec.

var promise = Promise.resolve({});

promise.then(function (value) {
    value.then = function (onFulfilled) {
        onFulfilled(125);
    };
    return promise;
}).then(function (value) {
    console.log(value); // what do they do here?
});

Is a more interesting example. If we follow the Promises/A+ spec, value should be an object (as per 2.3.2) although I suspect many implementations will behave incorrectly here, and if two promise implementations were to interact, it may instead log 125.

The ES6 spec is a little more difficult to dissect, but I think it suggests that it should log 125 in this instance because https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-resolve-functions doesn't appear to differentiate between thenables and true promises.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants