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

Javascript 使用异步/等待与承诺的区别?,javascript,node.js,promise,async-await,Javascript,Node.js,Promise,Async Await,我正在寻找在我的nodeJS应用程序中使用什么的答案 我有处理我对mssql的一般dB访问的代码。这段代码是使用异步函数编写的,然后我使用承诺调用该函数,一切正常 随着我的应用程序越来越大,代码越来越大,我计划将一些逻辑移到函数中,然后调用它们 所以我的问题是:混合使用async/await和promissions有缺点吗?还是真的没关系? Async/await使编写可读性更强的代码变得更容易,因为在返回某些内容之前,我必须读写多个db,并且我需要其中一些的结果 所以问题是什么是更好的方法?

我正在寻找在我的nodeJS应用程序中使用什么的答案

我有处理我对mssql的一般dB访问的代码。这段代码是使用
异步
函数编写的,然后我使用承诺调用该函数,一切正常

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

所以我的问题是:混合使用async/await和promissions有缺点吗?还是真的没关系?

Async/await使编写可读性更强的代码变得更容易,因为在返回某些内容之前,我必须读写多个db,并且我需要其中一些的结果

所以问题是什么是更好的方法? 已设置且无法更改的数据库层上的异步/等待 逻辑层async/await允许我在函数调用时使用async/and wait,或者如果我使用promise for logic,那么我就只能在函数调用时使用promise


因此,我希望有人能给我更多的见解,如果一个比另一个有更多的优势,除了能够编写更干净的代码。

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

注: 将等待调用放入
try/catch
,因为如果承诺失败,它会发出
“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模块实现之外,异步/等待之间没有任何性能差异


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

此时使用承诺的唯一原因是使用
promise.all()
调用多个异步作业,否则通常使用async/Wait或Observable会更好

这取决于您擅长的方法,promise和async/await都很好,但是如果您想使用同步代码结构编写异步代码,您应该使用async/await方法。如下面的示例所示,函数返回同时使用promise或async/await样式的用户。 如果我们使用承诺:

function getFirstUser() {
    return getUsers().then(function(users) {
        return users[0].name;
    }).catch(function(err) {
        return {
          name: 'default user'
        };
    });
}
如果我们使用aysnc/等待

async function getFirstUser() {
    try {
        let users = await getUsers();
        return users[0].name;
    } catch (err) {
        return {
            name: 'default user'
        };
    }
}
在promise方法中,我们需要遵循一个可扩展的结构,在async/await方法中,我们使用“await”来保持异步函数的执行


您可以查看此链接以了解更多信息,请访问async/await,这与承诺密切相关<代码>异步函数返回承诺,而wait是等待承诺被解析的语法糖。

混合使用promission和
async
函数的唯一缺点可能是代码的可读性和可维护性,但您当然可以将异步函数的返回值用作promission,也可以将
wait
用作返回promission的常规函数

您是否选择一个或另一个主要取决于可用性(您的node.js/browser是否支持
async
?)和您的审美偏好,但一个好的经验法则(基于我在撰写本文时的偏好)可能是:

如果需要串行运行异步代码:考虑使用<代码>异步/等待> /代码>: vs

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

如果需要并行运行:使用承诺。 有人建议您可以在表达式中使用
await
来等待多个任务,例如:
*注意,这仍然是从左到右依次等待的,如果您不希望出现错误,这是可以的。否则,由于
Promise.all()

(异步函数(){
函数t1(t){
time(`task${t}`);
log(`start task${t}`);
返回新承诺((解决、拒绝)=>{
设置超时(()=>{
timeEnd(`task${t}`);
解决();
},t);
})
}
log(“创建承诺”);
常数task1=t1(100);
常数task2=t1(200);
常数task3=t1(10);
log('wait for each task');
常量[r1,r2,r3]=[Wait task1,Wait task2,Wait task3];
console.log('Done');

}())
昨天,基于访问承诺链中以前的值的困难,我做出了一个临时决定,从使用承诺切换到使用异步/等待,独立于nodejs。我确实提出了一个紧凑的解决方案,使用“bind”将值保存在“then”函数中,但是异步在允许直接访问局部变量和参数方面似乎要好得多。当然,Async/Await更明显的优点是,它消除了显式的“then”函数,而采用了看起来很像普通函数调用的线性表示法

然而,我今天的阅读发现了Async/Await的问题,这使我的决定出轨。我想我会坚持承诺(可能使用宏预处理器使'then'函数看起来更简单),直到Async/Await得到修复,几年后

以下是我发现的问题。我很想知道我错了,这些问题都有简单的解决办法

  • 需要外部try/catch或最终承诺.catch(),否则将丢失错误和异常

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

  • 只能使用for/of正确地完成迭代,而不能使用其他迭代器

  • 等待一次只能等待一个承诺,而不是像承诺链那样的平行承诺

  • wait不支持Promise.race(),如果需要的话

  • Y
    return asyncFunction()
    .then(result => f1(result))
    .then(result2 => f2(result2));
    
    const result = await asyncFunction();
    const result2 = await f1(result);
    return await f2(result2);
    
    return asyncFunction()
    .then(result => {
      return f1(result)
      .then(result2 => f2(result, result2);
    })
    
    const result = await asyncFunction();
    const result2 = await f1(result);
    return await f2(result, result2);
    
    return Promise.all(arrayOfIDs.map(id => asyncFn(id)))
    
    const [r1, r2, r3] = [await task1, await task2, await task3];