javascript async / await与promise的区别

c86crjj0  于 2023-04-04  发布在  Java
关注(0)|答案(5)|浏览(182)

我正在寻找一个关于在我的nodeJS应用程序中使用什么的答案。
我有一段代码来处理我对mssql的通用dB访问。这段代码是用async函数写的,然后我用一个promise来调用这个函数,一切都很好。
随着我的应用程序越来越大,代码越来越多,我计划将一些逻辑转移到函数中,然后调用它们。
所以我的问题是:混合使用async/await和promises有什么缺点吗?还是真的没有关系?
Async / await使得编写可读性更强的代码变得更容易,因为在返回一些东西之前,我必须读取和写入多个数据库,并且我需要其中一些的结果。
那么问题是什么是更好的方法呢?在dB层上设置Async / await,并且不能更改逻辑层async / await允许我在函数调用上使用async /和await,或者如果我使用promise作为逻辑,那么我就会在函数调用上使用promise。
所以我希望有人能给予我更多的见解,如果一个比另一个有更多的优势,除了能够编写更干净的代码。

ktecyv1j

ktecyv1j1#

async/await和promise关系密切,async函数返回promise,await是语法糖,用于等待promise被解析。

混合使用promise和async函数的唯一缺点可能是代码的可读性和可维护性,但是您当然可以使用async函数的返回值作为promise,以及await作为返回promise的常规函数。
你是否选择一个还是另一个主要取决于可用性(你的node. js/浏览器支持async吗?)和你的审美偏好,但一个好的经验法则(基于我自己的偏好在写这篇文章时)可能是:

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

return asyncFunction()
.then(result => f1(result))
.then(result2 => f2(result2));

vs

const result = await asyncFunction();
const result2 = await f1(result);
return await f2(result2);

如果需要嵌套promise:使用async/await

return asyncFunction()
.then(result => {
  return f1(result)
  .then(result2 => f2(result, result2);
})

vs

const result = await asyncFunction();
const result2 = await f1(result);
return await f2(result, result2);

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

return Promise.all(arrayOfIDs.map(id => asyncFn(id)))

有人建议你可以在表达式中使用await来等待多个任务,如下所示:

**注意,这仍然是按从左到右的顺序等待,如果你不期望错误,这是可以的。否则,由于Promise.all()的快速失败行为,行为是不同的 *

const [r1, r2, r3] = [await task1, await task2, await task3];
(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一样,并行promise需要在出错的情况下正确处理。你可以阅读更多关于here的内容。
注意不要将前面的代码与下面的代码混淆:

let [r1, r2] = [await t1(100), await t2(200)];
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是一种更简洁的方法,可以更好地扩展到任意数量的任务。

sg24os4d

sg24os4d2#

实际上,这取决于你的节点版本,但如果你可以使用async/await,那么你的代码将更具可读性,更容易维护。当你定义一个函数为'async'时,它将返回一个原生的Promise,当你使用await调用它时,它将执行Promise.then。
注意:将await调用放在try/catch中,因为如果Promise失败,它会发出'catch',您可以在catch块中处理。

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
}

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

let result = await your-asyncFunction(parameters).catch((error)=>{//your error handler goes here});

所提到的这个方法不产生异常,因此执行继续。
我不认为async/await与原生Promise模块实现之间有任何性能差异。
我建议使用bluebird模块,而不是内置在node中的原生promise。

b1payxdu

b1payxdu3#

此时使用Promises的唯一原因是使用Promise.all()调用多个异步作业,否则通常使用async/await或Observables会更好。

xpcnnkqh

xpcnnkqh4#

这取决于你擅长的方法,promise和async/await都很好,但是如果你想写异步代码,使用同步代码结构,你应该使用async/await方法。像下面的例子,一个函数返回用户同时使用Promise或async/await风格。如果我们使用Promise:

function getFirstUser() {
    return getUsers().then(function(users) {
        return users[0].name;
    }).catch(function(err) {
        return {
          name: 'default user'
        };
    });
}

如果我们使用aysnc/await

async function getFirstUser() {
    try {
        let users = await getUsers();
        return users[0].name;
    } catch (err) {
        return {
            name: 'default user'
        };
    }
}

在promise方法中,我们需要遵循一个thenable结构,在async/await方法中,我们使用'await'来保持异步函数的执行。
你可以 checkout 此链接以获得更多清晰度访问https://medium.com/@bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8

wgxvkvu9

wgxvkvu95#

昨天我做了一个试探性的决定,从使用Promises切换到使用Async/Await,独立于nodejs,基于在Promise链中访问以前值的困难。我确实想出了一个紧凑的解决方案,使用'bind'将值保存在'then'函数中,但异步看起来更好Async/Await更明显的优点是,它允许直接访问局部变量和参数。消除了分散注意力的显式“then”函数,而采用了看起来很像普通函数调用的线性符号。
然而,我今天的阅读发现了Async/Await的问题,这使我的决定偏离了轨道。我想我会坚持使用Promises(可能使用宏预处理器来使“then”函数看起来更简单),直到Async/Await得到修复,几年后。
下面是我发现的问题。我很想知道我错了,这些问题有简单的解决方案。
1.需要一个外部的try/catch或final Promise.catch(),否则错误和异常将丢失。

  1. final await需要一个Promise.then()或一个额外的外部异步函数。
    1.迭代只能用for/of来完成,不能用其他迭代器。
  2. Await一次只能等待一个Promise,而不是像Promise. all中的Promise链那样的并行Promise。
  3. Await不支持Promise.race(),如果需要的话。

相关问题