【问题标题】:Javascript - async await vs promise callbackJavascript - 异步等待与承诺回调
【发布时间】:2018-03-02 08:09:16
【问题描述】:

我正在进行代码更改以将 .then(func{}) 样式代码转换为异步等待。

在我的示例中,从 then 转换为 async await,消除了并行查询 API 并按照请求完成的顺序处理它们的能力,因为两个请求彼此独立。

这是两种语法之间的有效区别,还是只是将两个函数分解为两个单独的异步函数以使它们并行运行?

升级前的示例代码:

componentDidMount() {
  this.loadLists();
}

loadLists() {
  console.log('start 1');
  api.get('/url/1').then(function(r) {
    console.log('done 1', r.body);
  });
  
  console.log('start 2');
  api.get('/url/2').then(function(r) {
    console.log('done 2', r.body);
  });
}

//OUTPUT
//start 1
//start 2
//done 1
//done 2

升级后的示例代码:

componentDidMount() {
  this.getLists();
}

async getLists() {
  console.log('start 1');
  var res = await api.get('/url/1');
  console.log('done 1', res.body);
  console.log('start 2');
  var res2 = await api.get('/url/2');
  console.log('done 2', res2.body);
}

//OUTPUT
//start 1
//done 1
//start 2
//done 2

编辑:

如果函数一分为二,async loadList1()async loadList2()

在没有await这个词的情况下调用这两个函数是否正确使用,这将导致两个请求(几乎)同时提交?

【问题讨论】:

  • 您可以使用 Promise.all 两者结合请求以保持并行处理它们。但是如果你想在其中一个完成后立即做某事,你最好单独处理 Promise。如果你不需要它,那么让它连续是没有意义的。
  • @IngoBürk 如果在两者都完成后我不需要做任何事情,我还需要使用 Promise.all 调用它们还是可以不使用 await 调用这些函数?

标签: javascript node.js reactjs asynchronous


【解决方案1】:

await 负责等待直到 promise 被解决。如果您希望请求并行运行,您可以简单地将它们都踢掉,然后await 他们:

console.log('start 1');
var res = api.get('/url/1');
console.log('start 2');
var res2 = api.get('/url/2');
console.log('done 1', (await res).body);
console.log('done 2', (await res2).body);

当然,这仍然会引入一些顺序依赖,因为您总是要在处理res 之前处理res2

如果您有更多的电话,Promise.all 仍然是要走的路。请记住,async/await 只是用于创建和解决 Promise 的语法糖。

【讨论】:

    【解决方案2】:
    componentDidMount() {
      this.getLists();
    }
    
    async getLists() {     
      const data = await Promise.all([api.get('/url/1'),api.get('/url/2')]);
      console.log('1st API Response ----> ',data[0].body);
      console.log('2nd API Response ----> ',data[1].body);
    }
    

    因此,您现在满足了并行执行两者的目标。 Promise.all([]) 这样做。现在由于Promise.all 返回了一个promise,你可以等待它。

    请不要忘记将您的函数包装在 try/catch 块中

    【讨论】:

      【解决方案3】:

      您可以执行以下操作:

      async function getLists() {
      
        const [res, res2] = await Promise.all([
          api.get('url/1'),
          api.get('url/2')
        ])
      
      }
      

      【讨论】:

        【解决方案4】:

        在您的第一个代码中,只有第一个 API 调用的 then 块内的任务在 API 调用任务完成后执行,但其他代码行将被执行。对于第二个 API 调用也是如此。

        在您的第二个代码中,

        var res = await api.get('/url/1');
        

        await API 调用会在它执行后阻塞任何代码,除非它的工作完成。

        【讨论】:

          猜你喜欢
          • 2018-10-17
          • 1970-01-01
          • 1970-01-01
          • 2017-06-15
          • 1970-01-01
          • 1970-01-01
          • 2019-07-20
          • 2019-05-05
          • 2021-10-07
          相关资源
          最近更新 更多