我如何从承诺链转到异步/等待多个承诺?

时间:2019-09-16 13:54:15

标签: javascript promise es6-promise

我进行了很多搜索,尝试了很多事情,但我不能得出一个明确的结论。我链接了很多承诺:

getInstalledComponents().call().then(response => {
    return {
        'installed_components': {
            'data': response
        }
    };
}).then((passed_data) => {
    return getDemosCategories().call().then(response => {
        return {...passed_data, ...{'demos_categories': response}};
    });
}).then((passed_data) => {
    return getDemosData().call().then(response => {
        return {...passed_data, ...{'demos_data': response}};
    });
}).then((passed_data) => {
});

我无法处理错误。我想以一种方式重新编写该代码,如果其中一个失败,则所有这些都应该失败并返回。

我尝试asy/await的每个promise函数,什么都没做。返回我需要的数据的承诺是getInstalledComponents, getDemosCategories, getDemosData,每个承诺都是基于Promise的AJAX调用。当AJAX调用返回时,基本上可以解决。

这看起来并不干净,也没有用。我该如何重写它以满足我的要求?

2 个答案:

答案 0 :(得分:2)

如果仅将catch块放在最后一个then的末尾,它将捕获任何函数中的错误。

Promise.reject("firstFailed")
  .then(passedData => console.log("second") || passedData)
  .then(passedData => console.log("third")  || passedData)
  .then(passedData => console.log("fourth") || passedData)
  .catch(error => console.error(error));

从上面的示例中缺少控制台日志可以看出,首先拒绝会停止执行任何其他then

答案 1 :(得分:2)

使用Promise.all,我们可以并行处理请求:

Promise.all([
  getInstalledComponents().call(),
  getDemosCategories().call(),
  getDemosData().call()
])
.then(([installedComponents, demosCategories, demosData]) => ({
  "installed-categories": { data: installedComponents },
  "demos-categories": { data: demosCategories },
  "demos-data": {data: demosData}
}))
.catch(e => handleSomeErrorForAnyOfRequestsAbove(e))

使用async/await仍然需要Promise.all

const result = {};
try {
  const [installedComponents, demosCategories, demosData] = await 
    Promise.all([
      getInstalledComponents().call(),
      getDemosCategories().call(),
      getDemosData().call()
    ]);
  result["installed-components"] = installedComponents;
  result["demos-categories"] = demosCategories;
  result["demos-data"] = demosData;

} catch(e) {
  handleSomeErrorFromAnyOfRequestFailed();
}