了解在哪里放置`await`关键字

时间:2019-01-16 02:09:53

标签: javascript asynchronous async-await

为了确保我了解async/await的工作原理,我想确认一下。首先让我创建几个函数:

let resolveAfter2Seconds = () => {
  console.log("starting slow promise");
  return new Promise(resolve => {
    setTimeout(function() {
      resolve(20);
      console.log("slow promise is done");
    }, 2000);
  });
};

let resolveAfter1Second = () => {
  console.log("starting fast promise");
  return new Promise(resolve => {
    setTimeout(function() {
      resolve(10);
      console.log("fast promise is done");
    }, 1000);
  });
};

现在,以这两个代码块为例:

let concurrentStart = async () => {
  console.log('==CONCURRENT START with await==');
  const slow = resolveAfter2Seconds();
  const fast = resolveAfter1Second();

  console.log(await slow);
  console.log(await fast);
}

现在,以上情况在功能上是否与此等效:

let concurrentStart = async () => {
  console.log('==CONCURRENT START with await==');
  const slow = await resolveAfter2Seconds();
  const fast = await resolveAfter1Second();

  console.log(slow);
  console.log(fast);
}

换句话说,我可以将await关键字放在函数调用await resolveAfter25Seconds()之前,或者...我可以将await放在触发该功能触发的控制台日志中- console.log(await slow);

在两种情况下async / await都将以相同的方式工作-在这种情况下,您可以通过两种方法完成相同的事情,因此结果是否相同?

1 个答案:

答案 0 :(得分:4)

他们的行为有所不同;您的第一个示例运行了两秒钟,而第二个示例运行了三秒钟。

在第一种情况下,慢速和快速允许并行启动;在第二种情况下,您甚至在开始第二个诺言之前就强迫第一个诺言解决。

如果您想并行获取多个URL,那么一个现实的用例是在没有await的情况下启动许多承诺。

// assuming getUrlContents() returns a Promise
let promises = [
    getUrlContents('http://url1.com/'),
    getUrlContents('http://url2.com/'),
    getUrlContents('http://url3.com/')
];

// all URLs are currently fetching

// now we wait for all of them; doesn't particularly matter what order
// they resolve
let results = [
    await promises[0],
    await promises[1],
    await promises[2]
];

此方法的另一种变体运行起来会慢得多(通常不是您想要的,除非您真的DID才能继续进行下一个操作之前就需要其中一个的内容):

let a = await getUrlContents('http://url1.com/')
let b = await getUrlContents('http://url2.com/')
let c = await getUrlContents('http://url3.com/')
let results = [ a, b, c ];

b的下载要等到a完成之后才能开始,依此类推。