1

我知道可以链接承诺,如下例所示:

// we also have deferA, deferB and deferC as the corresponding defer objects
promiseB = promiseA.then(function(result) {
    // do stuff to resolve B
});

promiseC = promiseB.then(function(result) {
    // do stuff to resolve C
});

现在,如果我调用deferA.resolve(data)this will resolve promiseA,它的then方法将运行,然后promiseB被解析。最后 promiseBthen将运行并解决promiseC。平坦而简单(希望我做对了)。

但是,如果 Promise 与自身链接会发生什么?

如果我把上面的例子改成这样:

// we also have deferA and deferB as the corresponding defer objects
promiseA = promiseA.then(function(result) {
    // do stuff to...?
});

promiseB = promiseA.then(function(result) {
    // do stuff to resolve B
});

deferA.resolve(data);

现在会发生什么?执行顺序是什么?

更重要的是,这个呢:

// we also have deferA and deferB as the corresponding defer objects
promiseA = promiseA.then(function(result) {
    // do stuff to...?
});

deferA.resolve(data);

promiseB = promiseA.then(function(result) {
    // do stuff to resolve B
});

在这种情况下会发生什么?

4

1 回答 1

5

这不是关于承诺,而是关于 JavaScript 中的引用。

当你这样做时:

p = p.then(function(){...

您正在更改p所指的承诺,您没有更改延迟对象在您完成/拒绝它时将解决的承诺 - 这与p您重新分配给它之前仍然相同。所以在你的示例代码中:

promiseA = promiseA.then(function(result) { // THIS WILL EXECUTE FIRST
    // do stuff to...?
});

promiseB = promiseA.then(function(result) { // THIS WILL EXECUTE SECOND
    // do stuff to resolve B
});

deferA.resolve(data);

当您将多个.then处理程序附加到一个承诺时,如下所示:

var p = first.then(...

var p2 = first.then(...

我在这里假设一个 Promises/A+ 实现。该规范保证两个.then处理程序都将在first完成时执行。它总是按照它们被添加的顺序发生。

因此,在上述情况下:

  • 第一个 promiseA 将解决
  • 然后上面的 promiseA.then 将运行(最先添加的那个)
  • 然后底部的promiseA.then就会运行(后面加的那个)

在添加之前或之后解决延迟.then不会以明显的方式改变结果(琐事:jQuery 承诺不是这种情况,这是他们的一个大问题)。


不过,可以创建一个循环的 Promise 链,只是有点困难。就像可以创建无限循环一样。好的 promise 库要么运行它,要么抛出一个循环引用错误。

于 2014-07-11T22:33:06.430 回答