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, время: 13:05. |