首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用异步/等待与承诺的区别?

使用异步/等待与承诺的区别?
EN

Stack Overflow用户
提问于 2018-10-30 03:46:19
回答 5查看 19.6K关注 0票数 28

我正在寻找一个关于在我的nodeJS应用程序中使用什么的答案。

我有处理对mssql的通用dB访问的代码。这段代码是使用async函数编写的,然后我使用了一个承诺来调用该函数,所有这些都很好。

随着我的应用程序越来越大,代码也越来越多,我计划将一些逻辑转换成函数,然后调用它们。

因此,我的问题是:是否存在使用异步/等待和许诺混合使用的缺点,或者这真的不重要?

异步/等待使编写更易读的代码变得更容易,因为在返回某些内容之前,我必须先读写多个db,并且需要其中一些结果。

所以问题是什么是更好的方法?异步/等待在已设置的dB层上,不能更改逻辑层异步/等待,这将允许我进行异步/等待函数调用,或者如果我对逻辑有承诺,那么在函数调用上就会被允诺所困。

因此,我希望有人能给我更多的洞察力,如果其中一个比另一个有更多的优势,除了能够写更干净的代码。

EN

回答 5

Stack Overflow用户

发布于 2018-10-30 05:08:30

async/await 与承诺密切相关。 async 函数返回承诺,等待是等待承诺得到解决的语法糖。

将承诺和async函数组合在一起的唯一缺点可能是代码的可读性和可维护性,但您当然可以将异步函数的返回值作为承诺使用,对于返回承诺的常规函数也可以使用await

您是选择一个还是另一个主要取决于可用性(您的node.js /浏览器支持async吗?)关于你的审美喜好,但一条好的经验法则(根据我在撰写本报告时的喜好)可以是:

如果您需要串联运行异步代码:请考虑使用async/await

代码语言:javascript
运行
复制
return asyncFunction()
.then(result => f1(result))
.then(result2 => f2(result2));

vs

代码语言:javascript
运行
复制
const result = await asyncFunction();
const result2 = await f1(result);
return await f2(result2);

如果您需要嵌套承诺:使用async/await

代码语言:javascript
运行
复制
return asyncFunction()
.then(result => {
  return f1(result)
  .then(result2 => f2(result, result2);
})

vs

代码语言:javascript
运行
复制
const result = await asyncFunction();
const result2 = await f1(result);
return await f2(result, result2);

如果您需要并行运行它:使用承诺。

代码语言:javascript
运行
复制
return Promise.all(arrayOfIDs.map(id => asyncFn(id)))

有人建议您可以在表达式中使用await等待以下多个任务:

*注意,这仍然是从左到右依次等待的,如果您不期望出现错误,这是可以的。否则,由于https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all#Promise.all_fail-fast_behaviour of Promise.all(),这种行为是不同的。

代码语言:javascript
运行
复制
const [r1, r2, r3] = [await task1, await task2, await task3];

代码语言:javascript
运行
复制
(async function() {
  function t1(t) {
    console.time(`task ${t}`);
    console.log(`start task ${t}`);
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.timeEnd(`task ${t}`);
        resolve();
      }, t);
    })
  }

  console.log('Create Promises');
  const task1 = t1(100);
  const task2 = t1(200);
  const task3 = t1(10);

  console.log('Await for each task');
  const [r1, r2, r3] = [await task1, await task2, await task3];

  console.log('Done');
}())

但是,与Promise.all一样,在发生错误时,需要正确地处理并行承诺。您可以阅读更多关于该这里的内容。

请注意,不要将前面的代码与以下代码混淆:

代码语言:javascript
运行
复制
let [r1, r2] = [await t1(100), await t2(200)];

代码语言:javascript
运行
复制
function t1(t) {
  console.time(`task ${t}`);
  console.log(`start task ${t}`);
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.timeEnd(`task ${t}`);
      resolve();
    }, t);
  })
}
console.log('Promise');
Promise.all([t1(100), t1(200), t1(10)]).then(async() => {

  console.log('Await');
  let [r1, r2, r3] = [await t1(100), await t1(200), await t1(10)]
});

使用这两种方法并不等同。阅读更多关于差异的文章

最后,Promise.all是一种更清晰的方法,可以更好地扩展到任意数量的任务。

票数 48
EN

Stack Overflow用户

发布于 2018-10-30 04:13:25

实际上,这取决于您的节点版本,但是如果您可以使用async/await,那么您的代码将更容易阅读和维护。当您将函数定义为‘异步’时,它将返回一个本机Promise,当您使用“等待”调用它时,它将执行Promise.then。

注意:将等待调用放在try/catch中,因为如果承诺失败,它会发出'catch',可以在catch块中处理。

代码语言:javascript
运行
复制
try{
let res1 = await your-async-function(parameters);
let res2 = await your-promise-function(parameters);
await your-async-or-promise-function(parameters);
}
catch(ex){
// your error handler goes here
// error is caused by any of your called functions which fails its promise
// this methods breaks your call chain
}

你也可以像这样处理你的“捕获”:

代码语言:javascript
运行
复制
let result = await your-asyncFunction(parameters).catch((error)=>{//your error handler goes here});

上述方法不会产生异常,因此执行将继续进行。

除了本机承诺模块实现之外,我认为async/await之间没有任何性能差异。

我建议使用bluebird模块,而不是内置到节点中的本地承诺。

票数 6
EN

Stack Overflow用户

发布于 2018-10-30 04:15:57

此时,使用承诺的唯一原因是使用Promise.all()调用多个异步作业,否则通常使用异步/等待或可观察性更好。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53057110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档