Async / await vs then 哪个最适合性能?
Posted
技术标签:
【中文标题】Async / await vs then 哪个最适合性能?【英文标题】:Async / await vs then which is the best for performance? 【发布时间】:2019-06-26 23:42:14 【问题描述】:我在 javascript 中有一个简单的代码,它在 API 中执行请求并返回响应,很简单。但在这种情况下,我将有数千个请求。那么,哪一个代码选项会执行得更好,以及为什么。还有哪一个被推荐为这些天的好习惯?
第一个选项是使用 .then 来解决承诺,第二个选项是使用 async / await。
在我的测试中,这两个选项的结果非常相似,没有显着差异,但我不确定规模。
// Using then
doSomething(payload)
const url = 'https://link-here/consultas';
return this.axios.get(url,
params:
token: payload.token,
chave: payload.chave,
,
).then(resp => resp.data);
// Using Async / await
async doSomething(payload)
const url = 'https://link-here/consultas';
const resp = await this.axios.get(url,
params:
token: payload.token,
chave: payload.chave,
,
);
return resp.data;
任何解释都会很有价值。
【问题讨论】:
您好!看看blog.pusher.com/promises-async-await。并且不要忘记用 try/catch 块包装你的 async/await 代码。 性能差异不应该是真正值得烦恼的事情:无论如何,http 请求肯定会占用 >99% 的执行时间。如果您可以并行启动几个请求,并通过Promise.all
加入他们的响应,则可以获得真正的收益。然后启动下一批,...等等。
我不确定这是否可以在这里应用,但请参阅来自 V8 开发人员的一般建议 at the end of this article:“赞成 async
函数和 await
而不是手写的承诺代码”。
@NikolayVetrov - 没有理由将await
包装在try/catch
中。 OP 只想返回被拒绝的承诺,async
函数将捕获拒绝并自动执行此操作。在比这更复杂的错误处理情况下,try/catch
将是必需的和有用的。
【参考方案1】:
await
只是.then()
的内部版本(基本上做同样的事情)。选择其中一个的原因实际上与性能无关,而是与所需的编码风格或编码方便性有关。当然,解释器内部有a few more opportunities to optimize things 和await
,但这不太可能是您决定使用哪个的方式。如果其他条件相同,我会选择await
,原因如上所述。但是,我会首先选择哪个使代码更易于编写、理解、维护和测试。
使用得当,await
经常可以save you a bunch of lines of code making your code simpler to read, test and maintain。这就是它被发明的原因。
您的代码的两个版本之间没有有意义的区别。当 axios 调用成功或出错时,两者都达到相同的结果。
如果您有多个需要序列化的连续异步调用,await
可以带来更多便利的不同之处。然后,与其将它们分别放在 .then()
处理程序中以正确链接它们,不如使用 await
并拥有更简单的代码。
await
和.then()
的一个常见错误是忘记正确的错误处理。如果您在此函数中的错误处理愿望只是返回被拒绝的承诺,那么您的两个版本都会这样做。但是,如果您连续有多个异步调用,并且您想要执行比仅返回第一个拒绝更复杂的操作,那么 error handling techniques for await
and .then()
/.catch()
就完全不同了,这似乎更简单取决于具体情况。
【讨论】:
对。使用'await'的另一个好处是功能明确标记【参考方案2】:这个帖子应该有一些更正。 await
和 .then
会给出非常不同的结果,并且应该用于不同的原因。
await
将等待某事,然后继续下一行。它也是两者中更简单的一个,因为它的机械行为更像是同步行为。您执行第 1 步,等待,然后继续。
console.log("Runs first.");
await SomeFunction();
console.log("Runs last.");
.then
从原始调用中分离出来并开始在自己的范围内运行,并将在原始范围无法预测的时间进行更新。如果我们可以暂时搁置语义,它会“更加异步”,因为它会离开旧范围并分支到新范围。
console.log("Runs first.");
SomeFunction().then((value) => console.log("Runs last (probably). Didn't use await on SomeFunction()."))
console.log("Runs second (probably).");
【讨论】:
为什么 await/.then 会给出不同的结果。它们旨在使用不同的语法来做同样的事情。其次,await
在技术上并不是阻塞行为,因为它不会阻塞线程。而且我不会将.then
描述为“更异步”。它们都是异步的,我认为这样考虑没有帮助。
请在您的回答中提供更多详细信息。正如目前所写的那样,很难理解您的解决方案。
我添加了一些清晰度来说明我的意思。这是两个非常不同的功能。显然更多的讨论涉及到异步,它属于完整指南,我清楚地在声明前加上“如果我们把语义放在一边。”【参考方案3】:
其实。 Await/Async 可以更有效地执行,因为 Promise.then() 在执行后失去了调用它的范围,您正在将回调附加到回调堆栈。
它的原因是:系统现在必须存储对调用 .then() 的位置的引用。如果出现错误,它必须正确指向错误发生的位置,否则,如果没有范围(因为系统在调用 Promise 后恢复执行,等待稍后返回 .then())它无法指向发生错误的地方。
Async/Await 暂停执行被调用的方法,从而保留引用。
【讨论】:
【参考方案4】:作为对@user280209 答案的更多解释,让我们考虑以下函数,它返回承诺并将其执行与.then()
和async await
进行比较。
function call(timeout)
return new Promise((resolve, reject) =>
setTimeout(() =>
console.log(`This call took $timeout seconds`);
resolve(true);
, timeout * 1000);
);
与.then()
(async () =>
call(5).then((r) =>
console.log(r);
);
await call(2); //This will print result first
await call(1);
)();
当运行上述调用时,日志将是
This call took 2 seconds
This call took 1 seconds
This call took 5 seconds
true
正如我们所见,.then()
在完成之前不会暂停其下一行的执行。
与async/wait
(async () =>
await call(5); //This will print result first
await call(2);
await call(1);
)();
当运行上述函数日志将是
This call took 5 seconds
This call took 2 seconds
This call took 1 seconds
所以我认为如果你的 promise 的结果不会用在下面的行中,.then()
可能会更好。
【讨论】:
感谢您提供的示例!在第一个call(5).then
上,它会在您等待await call(2)
和await call(1)
时在后台继续执行吗?【参考方案5】:
对于那些说 await 在异步调用返回之前阻塞代码的人来说,你没有抓住重点。 “await” 是 promise.then() 的语法糖。它有效地将函数的其余部分包装在它为您创建的 promise 的 then 块中。没有真正的“阻塞”或“等待”。
run();
async function run()
console.log('running');
makePromises();
console.log('exiting right away!');
async function makePromises()
console.log('make promise 1');
const myPromise = promiseMe(1)
.then(msg =>
console.log(`What i want to run after the promise is resolved $msg`)
)
console.log('make promise 2')
const msg = await promiseMe(2);
console.log(`What i want to run after the promise is resolved via await $msg`)
function promiseMe(num: number): Promise<string>
return new Promise((resolve, reject) =>
console.log(`promise`)
resolve(`hello promise $num`);
)
makePromises 中的 await 行没有阻塞任何东西,输出为:
正在运行 承诺 1 承诺 承诺 2 承诺 马上退出! promise 解决后我要运行的内容 hello promise 1 通过 await hello promise 2 解决 promise 后我想要运行的内容【讨论】:
以上是关于Async / await vs then 哪个最适合性能?的主要内容,如果未能解决你的问题,请参考以下文章
在 async/await 之后使用 .then 是一种好方法吗?
Flutter/Dart 中的 Future<void>, async, await, then, catchError