【问题标题】:AngularJS : Resolving self-chaining promisesAngularJS:解决自链接承诺
【发布时间】:2015-09-29 21:02:00
【问题描述】:

我知道 Promise 可以被链接起来,如下例所示:

// 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),这将解析promiseA,它的then 方法将运行,然后promiseB 被解析。最后 promiseB 的then 将运行并解析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
});

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

【问题讨论】:

  • What would happen .. 你不能将这些记录到控制台并找出来吗?
  • @charlietfl 当然可以,但我问的是它背后的逻辑和顺序。

标签: javascript angularjs promise angular-promise


【解决方案1】:

这不是关于承诺,而是关于 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 库要么运行它,要么抛出一个循环引用错误。

【讨论】:

  • 那么参考文献,如果我写deferA.promiseA = deferA.promiseA.then(...)呢?这肯定会改变 defer 对象。
  • @Xavier_Ex 取决于延迟的实现 - 这种事情(以及抛出安全性)是为什么一些库做 .promise() 而有些不让你直接访问延迟使用更好的 promise 构造函数。既然你标记了这个angularjs,你可以看到it won't change the defer object 的resolve 方法(只是它的.promise 值),因为它是闭包绑定的。不过,您绝对应该避免这种情况,这可能会在未来的 Angular 更新中发生变化。
  • 在您有p = first.then()p2 = first.then() 的示例中,您说.then() 处理程序将在first 被解析时运行并且它们将按顺序运行。这与first.then().then() 相同还是两个.then() 处理程序同步运行(第二个不等待第一个解决 - 它只是等待回调返回)?我的问题清楚了吗?
  • 如果你不重新分配 promiseA,两个.then 处理程序会按顺序同步运行,如果你按附加处理程序的顺序执行promiseA.then(..); promiseA.then(...),它们会异步运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多