[英]Async/await vs Promise
与最佳实践相混淆。
Using async-await is better than using promises.
这样对吗 ?
如何确定使用aync/await
和promises
?
下面我只写了两个代码段。 一个使用aync/await
,另一个不使用aync/await
。
哪个会更快?
案例1的优势是什么?
哪一种是最新的方法?
情况1
var promise1 = rp('https://api.example.com/endpoint1');
var promise2 = rp('https://api.example.com/endpoint2');
var response1 = await promise1;
var response2 = await promise2;
return response1 + ' ' + response2;
案例2
var promise1 = rp('https://api.example.com/endpoint1');
var promise2 = rp('https://api.example.com/endpoint2');
return Promise.all([promise1, promise2])
.then(function(values){
return values[0] + values[1];
});
使用async-await比使用promise更好
不, async
和await
是可以帮助您管理承诺的工具。
哪个会更快?
不可能有明显的区别
案例1的优势是什么?
有些人会认为它更容易理解。 其他人可能会不同意。
Async / await在后台转换为Promise。
因此,两者的性能是相同的。
除非存在一些技术限制,否则您应该始终使用async / await,因为它更容易理解。
现在,正如其他提到的那样,目前两个代码示例不相等。 但是由于您正在使用await
,这意味着您的rp()
返回了一个promise。 因此,您可以将第一种情况改写为:
let [r1, r2] = await Promise.all([promise1, promise2])
return r1 + r2
达到同样的效果。
使用async-await比使用promise更好。
哪个会更快?
哪一种是最新的方法?
语法和您的方法都不提供相对于其他方法的任何特殊优势,但是此外,您的方法不能很好地展现您的意图。 您无需保留对promise的明确引用即可同时获得其结果:
const [response1, response2] = await Promise.all([
rp('https://api.example.com/endpoint1'),
rp('https://api.example.com/endpoint2')
]);
...
请记住,上述方法必须包含在async
函数中。 它不能像这种方法那样存在于顶级范围内:
Promise.all([
rp('https://api.example.com/endpoint1'),
rp('https://api.example.com/endpoint2')
]).then(([response1, response2]) => {
...
});
当前所有的回答当然都是正确的,但是请记住一些差异。
当前,在您的两个解决方案中,承诺都是并行调用的。 这可能会导致一些错误。
考虑这种情况(对情况1的轻微修改):
var response1 = await rp('https://api.example.com/endpoint1');
var response2 = await rp('https://api.example.com/endpoint2');
return response1 + ' ' + response2;
在上述情况下promise2
AFTER将被执行promise1
完成执行本身。 启动promise2
时,结果是已知的。 另一方面,您的案件会在某种竞赛中一起运行。 因此,如果在第二次调用rp
包含的逻辑取决于第一次调用rp
所执行的某些操作,则可能导致意外结果甚至崩溃。 一个很好的例子是写入和读取相同的文件。
让我们考虑以下示例:
function writeToFile()
{
return new Promise((resolve, reject) => {
... // writing to file abc.txt
};
}
function readFile()
{
return new Promise((resolve, reject) => {
... // reading file abc.txt
};
}
function raceCondition()
{
Promise.all([
writeToFile(),
readFile()
]);
}
async function asyncAwait()
{
await writeToFile();
await readFile();
}
raceCondition()
函数可能会导致意外行为,因为readFile可能在writeToFile
函数甚至还没有完成写入文件的情况下运行。 这可能导致读取一些旧数据,甚至可能根本不存在文件。
asyncAwait()
函数使用async / await方法,以确保writeToFile()
函数在读取开始之前完成其工作。 当然,这并不意味着程序会变得同步。 同时,执行其他操作(即某些GUI事件处理等)。
然后应将Async / Await视为.then()。then()链的替代方案,而不是Promise.all
等待用于评估已解决或已拒绝的Promise。 因此,使用.then和await的功能是相同的。 但是,由于您不会陷入一系列回调,因此await使得代码更具可读性。 使用await时,您可以将async函数视为使用await的同步函数。
让我们举个例子。 我们有一个API和2个数据库,我们想从其中一个数据库取一个名称,然后插入另一个数据库。 为此,我们必须从数据库1中获取数据。等待数据到达客户端,然后通过POST请求将其发送到要插入的API。 [您可以使用一个功能服务器端完成所有这些操作,但对于我们来说,我们将发出2个异步获取请求来回答此问题]。 如果我们想在函数中使用.then来解决这个问题,它将看起来像这样。
function get_and_set(){
fetch("https://www.some_api.com/get_random_name")
.then( response => response.text() )
.then( name => {
fetch("https://www.some_api_2.com/insert_name", {
headers : {
"Body-Type" : "application/json",
"Accept" : "application/json"
},
method : "POST",
body : JSON.stringify({ name : name })
})
.then( set_response => set_response.text() )
.then( set_response => {
return set_response;
})
)}
}
如果我们选择在await中使用异步函数,则可以这样编写。 我个人认为这更具可读性。
async function get_and_set(){
let response = await fetch("https://www.some_api.com/get_random_name")
let name = response.text();
let insert_response = await fetch("https://www.some_api_2.com/insert_name", {
headers : {
"Body-Type" : "application/json",
"Accept" : "application/json"
},
method : "POST",
body : JSON.stringify({ name : name })
});
let success = insert_response.text();
return (success); //Return the status of how the insertion went
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.