了解Async / await确实很有用,但是要考虑一些缺点。
异步/等待使您的代码看起来同步,并以某种方式使其行为更加同步。在await
所有的代码块关键字执行后面,直到承诺履行,正是因为它会与同步操作。它的确允许其他任务在此期间继续运行,但是您自己的代码被阻止了。
这意味着您的代码可能会因大量彼此接连发生的等待的承诺而变慢。每个都await
将等待上一个完成,而实际上您想要的是诺言同时开始处理,就像我们不使用异步/等待时所做的那样。
有一种模式可以缓解此问题:通过将Promise
对象存储在变量中,然后等待所有这些过程来启动所有的Promise过程。让我们看一些证明这一概念的例子。
我们提供了两个示例-slow-async-await.html(请参阅源代码)和fast-async-await.html(请参见源代码)。两者都以自定义的promise函数开始,该函数通过setTimeout()
调用伪造异步进程:
function timeoutPromise(interval) {
return new Promise((resolve, reject) => {
setTimeout(function(){
resolve("done");
}, interval);
});
};
然后每个timeTest()
函数都包含一个异步函数,等待三个timeoutPromise()
调用:
async function timeTest() {
...
}
每个人都以记录开始时间,看待timeTest()
诺言需要多长时间来结束,然后记录结束时间并报告操作总共花了多长时间而结束:
let startTime = Date.now();
timeTest().then(() => {
let finishTime = Date.now();
let timeTaken = finishTime - startTime;
alert("Time taken in milliseconds: " + timeTaken);
})
timeTest()
在每种情况下,其功能都不同。
在slow-async-await.html
示例中,timeTest()
如下所示:
async function timeTest() {
await timeoutPromise(3000);
await timeoutPromise(3000);
await timeoutPromise(3000);
}
在这里,我们只是直接等待所有三个timeoutPromise()
呼叫,使每个警报持续3秒钟。随后的每个实例都被迫等到最后一个实例完成-如果运行第一个示例,您将看到警报框报告总运行时间约为9秒。
在fast-async-await.html
示例中,timeTest()
如下所示:
async function timeTest() {
const timeoutPromise1 = timeoutPromise(3000);
const timeoutPromise2 = timeoutPromise(3000);
const timeoutPromise3 = timeoutPromise(3000);
await timeoutPromise1;
await timeoutPromise2;
await timeoutPromise3;
}
在这里,我们将三个Promise
对象存储在变量中,这具有抵消所有关联对象同时运行的作用。
接下来,我们等待它们的结果-因为所有的诺言基本上都在同一时间开始处理,所以诺言将全部同时履行;当您运行第二个示例时,您将看到警报框报告总运行时间刚刚超过3秒!
您必须仔细测试代码,如果性能开始下降,请记住这一点。
另一个不便之处是您必须将等待的诺言包装在异步函数中。