繁体   English   中英

异步/等待vs承诺

[英]Async/await vs Promise

与最佳实践相混淆。

Using async-await is better than using promises. 这样对吗 ?

如何确定使用aync/awaitpromises

下面我只写了两个代码段。 一个使用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更好

不, asyncawait是可以帮助您管理承诺的工具。

哪个会更快?

不可能有明显的区别

案例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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM