如何在 ES 2017 中链接来自异步函数的 return 值?

How do I chain return values from async functions in ES 2017?

我正在尝试这样做:

service.getConfig()
.then(cfg => service.getData())
.then(data => service.process(data,cfg))
.then(results => console.log(results))
.catch(err => console.log(err));

这里明显的问题是 cfg 在第二个 .then 块中超出了范围。我可以通过许多混乱的方法来解决这个问题,例如通过在外部作用域中声明 cfg,或者通过 service.getData() 某种方式传递 cfg 并返回 [data,cfg]。但是有没有一种很好的编码方式,同时又不会失去链式承诺和单行箭头函数的美丽简洁优雅?

使用 async / await 然后箭头函数变成表达式,变量保留在范围内。

async function someFunction() {
    try {
        const cfg = await service.getConfig();
        const data = await service.getData();
        const results = await service.process(data, cfg);
        return results;
    } catch (err) {
        console.log(err);
    }
}

虽然这是 ES8 而不是 ES6。

假设您实际上不需要 运行 service.getConfig()service.getData() 之前(因为 service.getData() 没有收到任何参数)。您可以像这样并行使用 Promise.all 到 运行 这两个任务:

Promise.all([service.getConfig(), service.getData()])
  .then(([cfg, data]) => service.process(data, cfg))
  .then((results) => console.log(results))
  .catch((err) => console.log(err));

正如你在这个例子中所说的那样,调用顺序无关紧要运行它们并行是可行的方法。

但出于兴趣,如果调用顺序确实很重要,那么通过链传递 datacfg 的方式仅使用 'native' 承诺(并且不必更改如您所说,service.getData() 通过 cfg 的实现将使用内部 then,如下所示:

service.getConfig()
  .then(cfg => service.getData().then(data => ({ data, cfg })))
  .then(({ data, cfg }) => service.process(data, cfg))
  .then(results => console.log(results))
  .catch(err => console.log(err));