Promise/A+ test case
не могу понять такой test case:
Код:
2.3.3: Otherwise, if `x` is an object or function, thenable-объект понятно
var y = {
then: function (…) {
…
}
};
а как будет выглядеть "a thenable for a thenable"?! :D по описанию тест кейса в голове рисуется что-то типа такого:
var x = {
then: function (resolvePromise) {
resolvePromise(y);
}
};
var y = {
then: function (onFulfilled) {
onFulfilled('y1');
onFulfilled('y2');
}
};
new Promise(function (resolve) {
x.then(resolve);
}).then(function (value) {
console.log('value =', value);
}, function (reason) {
console.log('reason = ', reason);
});
но этот код работает без ошибок, в консоль выводится "y1" |
Я так понял, тут вот о чем:
var y = {
then: function (resolvePromise) {
console.log("y.then()");
resolvePromise('y1');
}
};
var x = {
then: function (resolvePromise) {
console.log("x.then()");
resolvePromise(y);
}
};
var pro = new Promise(function (resolve) {
console.log("Promise: resolve(x);");
resolve(x);
});
pro.then(function (value) {
console.log('value =', value);
});
"х" - просто thenable, его в 17 строке передаем в resolve. А "y" - thenable for a thenable, потому что его передаем в resolvePromise внутри x.then. Передача thenable в resolve/resolvePromise приводит к тому, что у этих объектов вызывается then, чтобы узнать итоговое значение всего промиса (в то время как не-thenable объект сам пошел бы в качестве значения. Т.е. в итоговое значение промиса никак нельзя передать объект с методом then). И вот тут обнаружилось разное поведение в Хроме и Fx, которое видно, если pro.then поместить в setTimeout: Fx "прокручивает" все then во время resolve промиса (строка 17), а Хром - в момент вызова pro.then. Кто из них прав, я понять так и не смог. |
странно, resolver по спецификации синхронный, в Chrome 41 вроде так же как в Firefox
еще вот такую штуку нашел http://modernjavascript.blogspot.ru/...c-through.html слайд №18 все равно не пойму на чем в этом тесте фейлится мой велосипед, вот тут https://github.com/getify/native-promise-only/issues/5 выяснили, что then всегда должен быть асинхронным… |
Пофиксил вот такой случай:
var testValue = 'test value';
var testReason = new Error('test error');
var thenable = {
then: function (resolvePromise, rejectPromise) {
resolvePromise(testValue);
reject(testReason);
}
};
var deferred = {};
var promise = new Promise(function (resolve, reject) {
deferred.resolve = resolve;
deferred.reject = reject;
resolve(thenable);
});
deferred.resolve('other test value');
deferred.reject(new Error('other test error'));
promise.then(function (value) {
console.log('value = "' + value + '"', value === testValue);
}, function (reason) {
console.log('reason = "' + reason + '"', reason === testReason);
});
и тест 2.3.3.3 перестал фейлиться Теперь все 872 теста пройдены :dance: |
| Часовой пояс GMT +3, время: 16:39. |