我应该使用异步/等待还是承诺?

时间:2018-10-30 03:46:20

标签: javascript node.js promise async-await

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

我有用于处理对mssql的通用dB访问的代码。这段代码是使用async函数编写的,然后我使用了一个Promise来调用该函数,并且一切正常。

随着我的应用程序越来越大,代码越来越大,我计划将一些逻辑移到函数中,然后调用它们。

所以我的问题是:使用异步/等待和承诺的组合是否有缺点,还是真的没关系?

异步/等待使编写更具可读性的代码变得更加容易,因为我必须先读写多个数据库,然后再返回某些东西,而我需要其中的一些结果。

所以问题是什么是更好的方法? 已设置且无法更改的异步/正在等待的dB层 逻辑层async / await允许我异步/并在函数调用中等待,或者如果我接受逻辑承诺,那么我会在函数调用时陷入promise。

因此,我希望有人可以给我更多的见解,除了能够编写更简洁的代码之外,是否还具有其他优势。

5 个答案:

答案 0 :(得分:7)

$arr = array(array( 'id'=> 2, 'admission_no' => 4254, 'status' => 'failure' ),array( 'id'=> 3, 'admission_no' => 4254, 'status' => 'failure' ),array( 'id'=> 4, 'admission_no' => 4254, 'status' => 'failure' )); array_walk($arr, function (&$value) { $value[0] = 'TVIS Velammal Vidyalaya, Ponneri'; }); echo "<pre>"; print_r($arr); 与承诺紧密相关。 Array ( [0] => Array ( [id] => 2 [admission_no] => 4254 [status] => failure [0] => TVIS Velammal Vidyalaya, Ponneri ) [1] => Array ( [id] => 3 [admission_no] => 4254 [status] => failure [0] => TVIS Velammal Vidyalaya, Ponneri ) [2] => Array ( [id] => 4 [admission_no] => 4254 [status] => failure [0] => TVIS Velammal Vidyalaya, Ponneri ) ) 函数返回承诺,而等待是等待承诺被解决的语法糖。

将promise和async/await函数混合使用的唯一缺点可能是代码的可读性和可维护性,但是您当然可以将异步函数的返回值用作promise和async用于可以返回承诺的常规函数​​。

是否选择一个与另一个相对,主要取决于可用性(您的node.js /浏览器是否支持async?)和您的审美偏好,但是有一个很好的经验法则(基于我自己的偏好)写作时间)可以是:

如果您需要连续运行异步代码:请考虑使用await

async

vs

async/await

如果您需要嵌套的Promise:请使用return asyncFunction() .then(result => f1(result)) .then(result2 => f2(result2));

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

vs

async/await

如果需要并行运行:请使用promises。

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

注意:建议您可以使用await并行运行任务,如下所示:

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

但是实际上,这将按顺序运行任务:

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

所以这不是等效的。 Read more

答案 1 :(得分:2)

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

答案 2 :(得分:0)

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

注意: 将您的等待呼叫放入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});

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

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

我建议使用bluebird模块,而不是内置在节点中的本机Prom。

答案 3 :(得分:0)

这取决于您使用哪种方法,promise和async / await都不错,但是如果您要编写异步代码,则应使用异步代码结构使用async / await方法。例如以下示例,函数返回具有Promise或异步/等待样式的用户。 如果我们使用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方法中,我们需要一个可遵循的结构,在async / await方法中,我们需要使用“ await”来保持异步功能的执行。

您可以检出此链接以更清楚地访问https://medium.com/@bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8

答案 4 :(得分:0)

昨天,基于访问Promise链中以前的值的困难,我做出了一个暂时的决定,即从使用Promises切换到使用独立于nodejs的Async / Await。我确实提出了一个紧凑的解决方案,使用“ bind”将值保存在“ then”函数中,但是Async在允许直接访问局部变量和参数方面似乎更好(而且确实如此)。而且,Async / Await更明显的优势当然是消除了分散注意力的显式“ then”函数,转而采用看起来与普通函数调用类似的线性表示法。

但是,我今天的阅读发现了Async / Await的问题,这使我的决定陷于混乱。我认为我会坚持Promises(可能使用宏预处理程序使'then'函数看起来更简单)直到几年后Async / Await得到修复。

这是我发现的问题。我很想知道我错了,这些解决方案很简单。

  1. 需要外部try / catch或最终的Promise.catch(),否则将丢失错误和异常。

  2. 最后的等待需要Promise.then()或额外的外部异步函数。

  3. 只能使用for / of正确地进行迭代,而不能使用其他迭代器来完成。

  4. “等待”一次只能等待一个Promise,而不能像Promise.all那样并行处理Promise链。

  5. Await不支持Promise.race(),如果需要的话。