如何在 ES 2017 中链接异步函数的返回值?

Posted

技术标签:

【中文标题】如何在 ES 2017 中链接异步函数的返回值?【英文标题】:How do I chain return values from async functions in ES 2017? 【发布时间】:2020-10-25 08:18:22 【问题描述】:

我正在尝试这样做:

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]。但是有没有一种很好的方法来编写这个代码而不失去链式承诺和单行箭头函数的美丽简洁优雅?

【问题讨论】:

这能回答你的问题吗? How do I access previous promise results in a .then() chain? 【参考方案1】:

正如您在本示例中所说,调用顺序无关紧要,并行运行它们是可行的方法。

但只是出于兴趣,如果调用顺序确实很重要,那么仅使用“本机”承诺通过链传递 datacfg 的方式(并且不必更改 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));

【讨论】:

【参考方案2】:

假设您实际上不需要在service.getData() 之前运行service.getConfig()(因为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));

【讨论】:

【参考方案3】:

使用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。

【讨论】:

对不起,你是对的,我的意思是放 ES2017,而不是 ES6。我更新了问题。不过感谢您的回答...我很想看看是否还有其他方法可以做到这一点。

以上是关于如何在 ES 2017 中链接异步函数的返回值?的主要内容,如果未能解决你的问题,请参考以下文章

ES7 - 如何停止(剪切)异步/等待链接

ES6 之 async函数

返回一个等待的值返回一个 Promise? (es7 异步/等待)

如何从异步调用返回响应

ES6之Generator 函数的异步应用

ES8 立即调用异步函数表达式