承诺链在最后一个承诺解决之前解决

时间:2017-11-23 00:27:45

标签: javascript jquery promise

背景
从2个几乎相同的javascripts开始,然后重构为3:一个包含以前冗余代码+ 2个调用脚本的实用程序脚本。

问题
两个原始脚本使用jquery Deferreds(when.then)并且工作正常。 3脚本方案失败,因为倒数第二个承诺从一个调用脚本中解析早期

详情
第一个脚本,称之为" multi"使用一系列延迟来遍历一系列的ajax请求,然后刷新" multi"浏览器中的页面。所以:

auth -> user -> loop (updateIssue -> transition) end loop -> refresh

第二,"单身"在没有循环的情况下有效地使用相同的代码,然后使用不同的refresh函数

我的目标是将代码重构为实用程序脚本中的promise链,并使用如下:

// calling script
Utility.promiseChain().done(refresh())

// utility script
Utility.promiseChain = function() {
return authPromise()
.then(function() { return userPromise();} )
.then(function() { return Promise.all(array of update.then(transition) promises);})} 

问题,更具体地说
Promise.all调用始终在update之后解析,但在transition之前解析,导致refresh提前触发,然后是transition。您可以提供的任何见解将是最有帮助的。

2 个答案:

答案 0 :(得分:0)

  

Promise.all调用ALWAYS在更新后但在转换之前解析

唯一可能发生的方法是,如果您的事件链中的某些内容没有正确地链接承诺。您必须向我们展示真实的代码,以帮助您确定具体问题,但如果Promise.all()没有等待transition承诺,那么该承诺不能正确地链接到数组中Promise.all()等待的承诺。

具体来说,我们需要看到伪代码的这一部分背后的代码:

array of update.then(transition) promises

准确了解transition()如何参与创建承诺数组。  与往常一样,如果您向我们展示您的REAL代码而不仅仅是伪代码,我们可以帮助您找到编程逻辑中实际错误的来源。

答案 1 :(得分:0)

可能的情况是您正在使用JQuery<版本3,对authPromise()的调用返回JQuery承诺。这意味着thenUtility.promiseChain返回的promise链中返回的所有promise都是JQuery的承诺。我最后一次检查时,旧版本的JQuery不承认外部库承诺,包括本机Promise构造函数返回的承诺,作为承诺,履行一个JQuery承诺解决了一个没有等待它的结算。

Promise.all

中返回的promise对象可能有效
.then(function() { return Promise.all( // ...

用于履行then返回的承诺,而无需等待其解决。

简而言之,您无法通过ES6承诺解决旧版本的JQuery承诺,并产生解决带有承诺的承诺的效果。

潜在的解决方案:

  1. 升级到JQuery 3(你失去了对旧版本IE的支持,但这些都不支持Promise)。如果可以的话,建议使用。

  2. 将所有承诺用法转换为ES6样式承诺,并通过调用Promise.resolve( jqPromise)

  3. 转换任何在使用前传递给ES6承诺的JQuery承诺
  4. 反向编写等效的Promise.resolve,将ES6承诺转换为JQuery承诺。我会尽可能地评价这一点,但是朝着错误的方向倒退。