嵌套的承诺以及如何绕过它们

时间:2016-11-05 00:47:53

标签: javascript node.js promise

我正在使用承诺从URL获取一些JSON。返回的JSON包含返回JSON的新URL列表。由于嵌套的承诺,我当前的实现失败了。

我需要执行以下操作:

  1. 请求父级JSON网址
  2. 请求每个子JSON网址
  3. 在每个子承诺返回JSON之后,我需要对孩子的JSON和父JSON做一些事情。
  4. 我收到以下错误。

    Warning: a promise was created in a handler at main.development.js:661:61 but was not returned from it

    我的代码的简化版本:

    myPromise(url)
      .then(response => {
        // process the data into an array of items
       items.forEach(item => {
          myPromise(item.url)
            .then(response2 => {
              // Do a thing here with data from response and response2
            });
        });
      });
    

2 个答案:

答案 0 :(得分:1)

我已经使用Bluebird地图完成了您的示例。

我还添加了并发选项,这非常方便..离开,只是像promise.all一样工作,并且值为1,你想做所有的承诺吗?串联..



myPromise(url)
  .then(response => {
    // process the data into an array of items
   return Promise.map(items, item => {
     return myPromise(item.url)
        .then(response2 => {
          // Do a thing here with data from response and response2
        });
    }, {concurrency:10});  //lets do a max of 10 promises at a time.
  });




答案 1 :(得分:1)

您的错误实际上只是一个警告。这是有充分理由的;一个常见的错误是做这样的事情

myPromise(url)
    .then(response => {
        somethingElseAsync(response);        
    })
    .then(myCallback);

并期望在myCallback完成工作后调用somethingElseAsync。据我所知,这不是你的情况,因为你没有收集孩子承诺的结果。

要取消警告,您可以关注Keith's answer。作为奖励,您可以在您的连锁店上追加另一个承诺,这将在所有子承诺得到解决时解决。

作为Promise.map的替代方案,如果您可以同时生成所有子任务,则可以使用Promise.all,如下所示:

myPromise(url).then(response => {
    return Promise.all(items.map(item => {
        return myPromise(item.url).then(response2 => {
            // handle response and response2, return some result
            return result;
        });
    }));
}).then(results => {
    //    ^^^ an array of results returned from child promise callbacks
}).catch(error => {
    // either the parent promise or one of the child promises has rejected
});
相关问题