Рубиновое сумасшествие: класс против объекта?

О разрешении обещаний

То, что вы наблюдаете здесь, называется рекурсивным then разрешением. Процесс разрешения обещаний в спецификации Promises / A + содержит следующее предложение:

onFulfilled или onRejected возвращает значение x, запускает процедуру разрешения обещаний [[Resolve]] (prom2, x)

Спецификация обещания ES6 (обезвреживание обещаний) содержит аналогичное предложение.

Это означает, что когда выполняется операция resolve: либо в конструкторе обещаний, вызвав Promise.resolve или в вашем случае в цепочке then реализация обещания должна рекурсивно разворачивать возвращаемое значение, если это обещание.

На практике

Это означает, что если onFulfilled ( then) возвращает значение, попробуйте «разрешить» значение обещания самостоятельно, таким образом, рекурсивно ожидая всю цепочку.

Это означает следующее:

promiseReturning().then(function(){
    alert(1);
    return foo(); // foo returns a promise
}).then(function(){
    alert(2); // will only run after the ENTIRE chain of `foo` resolved
              // if foo OR ANY PART OF THE CHAIN rejects and it is not handled this 
              // will not run
});

Итак, например:

promiseReturning().then(function(){
    alert(1);
    return Promise.resolve().then(function(){ throw Error(); });
}).then(function(){
    alert("This will never run");
});

И что:

promiseReturning().then(function(){
    alert(1);
    return Promise.resolve().then(function(){ return delay(2000); });
}).then(function(){
    alert("This will only run after 2000 ms");
});

Is это хорошая идея?

Это была тема много дискуссий в процессе спецификации обещаний, был обсужден второй цепной метод, который не демонстрирует такого поведения, но решил против (все еще доступен в Chrome, но скоро будет удален ). Вы можете прочитать о всех дискуссиях в этой эдисковой цепочке .

На других языках

Следует упомянуть, что другие языки этого не делают, ни фьючерсы в Scala, ни фьючерсы в Scala или задачи в C # имеют это свойство. Например, в C # вам нужно будет вызвать Task.Unwrap в задаче, чтобы дождаться, когда ее цепочка будет разрешена.

65
задан Andrew Grimm 27 January 2012 в 00:41
поделиться