Promises.all()中断顺序链接

时间:2019-02-06 21:01:29

标签: javascript promise

过去,我曾经使用过jQuery延迟/承诺,但是我试图转向javascript承诺。我有一个功能,需要按顺序进行多个网络调用,然后可以按任何顺序进行多个网络调用,但是所有这些都需要解决,然后再继续进行。我先从顺序调用开始,然后按顺序进行,但随后从第二次调用的结果开始,我需要遍历这些结果,并在随后的调用中生成可变数量(目前为6)。我不在乎这些命令的执行顺序,但是在我继续之前,确实需要等待所有命令解决。我认为这种模式会奏效。但事实并非如此。

function doLotsOfStuff(){

    firstNetworkCall()
        .then(function(data){
            // do stuff with data
            return secondNetworkCall();
        })
        .then(function(data){
            // do stuff with data

            var promises = data.map(function(item){
                // All of these calls (happens to be 6)
                // need to be done before I continue
                return thirdIndependentCall(item.Info);
            });

            // at this point I see [Promise, Promise, ....]
            // all are unresolved

            return Promise.all(promises);
        })
        .then(function(results){
            // executes immediately after the Promises.all() line
            // none of them are resolved
            // results is just one unresolved promise
        });
}

我可以像这样将最后一步链接到Promises.all()

return Promise.all(promises)
        .then(function(results){
            // this works!
         })

但是,如果之后我想链接更多的东西,我必须继续将它们插入。好像我正在丢失一些信息。

编辑

我在简化代码中复制了错别字,而在我的实际代码中却没有。在链中添加.catch()的建议是一个很好的建议,我尝试了一下。现在它抛出firstNetworkCall(...).then(...).then(...).catch is not a function.

我认为问题在于我的某些代码(仍在某处)仍依赖于jQuery.Deffered,并且在Promise中不能很好地发挥作用。

很高兴知道我的初始模式应该可以工作-如果我与正在使用的异步处理类型保持一致。

1 个答案:

答案 0 :(得分:4)

更改此:

Promises.all(promises)

对此:

Promise.all(promises)

您所拥有的东西将引发异常(因为未定义Promises捕获的.then(),然后拒绝了Promise链。

这是经典的原因,为什么在链的末尾始终应该有一个.catch(),因为如果记录该拒绝,它可能会告诉您错误是什么。


如果要将任何jQuery Promise转换为ES6 Promise,以便可以在任何地方使用.catch()或仅保证一致的行为,则可以用Promise.resolve()将它们包装起来,如下所示:

       Promise.resolve(firstNetworkCall()).then(...).catch(...)

或者这个:

       var promises = data.map(function(item) {
            // All of these calls (happens to be 6)
            // need to be done before I continue
            return Promise.resolve(thirdIndependentCall(item.Info));
        });

        // at this point I see [Promise, Promise, ....]
        // all are unresolved

        return Promise.all(promises);

并且请记住,某些较新的jQuery版本比其他版本更兼容ES6 Promise。