如何在同步功能中等待JavaScript中的异步调用?

如何在同步功能中等待JavaScript中的异步调用?,第1张

如何在同步功能中等待JavaScript中的异步调用?

但问题是-异步方法仅允许等待。

确实,没有,没有解决方法。Javascript的运行到完成语义 要求
在任何未决的异步 *** 作(例如,对XHR异步调用的XHR处理程序的回调)能够运行之前,同步功能必须完成。

Javascript在给定线程上运行的方式是它处理作业队列1:

  1. 接下一个待处理的工作
  2. 同步执行该作业的代码
  3. 只有当该工作完成后,才返回到步骤1接下一个工作

(这要复杂一点,它有两个层次,但这与这个特定问题无关。)

XHR补全等都是在队列中安排的作业。无法暂停作业,从队列中运行另一个作业以及拾取已暂停的作业。

async
/ 为处理异步 *** 作
await
提供了非常简单的
语法 ,但它们不会改变作业队列的性质。

对于您的情况,我看到的唯一解决方案是一直一直到顶层。这可能没有您想像的那么复杂(也许会如此)。在许多情况下,它是

async
function
许多功能之前添加的。但是,使这些功能异步可能会产生重大的连锁反应(例如,在事件处理程序中同步的事物变为异步的事物会更改与UI有关的发生时间)。

例如,考虑以下同步代码:

var btn = document.getElementById("btn");btn.addEventListener("click", handler, false);function handler(e) {  console.log("handler triggered");  doSomething();  console.log("handler done");}function doSomething() {  doThis();  doThat();  doTheOther();}function doThis() {  console.log("doThis - start & end");}function doThat() {  console.log("doThat - start");  // do something that takes a while  var stop = Date.now() + 1000;  while (Date.now() < stop) {    // wait  }  console.log("doThat - end");}function doTheOther() {  console.log("doThat - start & end");}.as-console.wrapper {  max-height: 80% !important;}<input type="button" id="btn" value="Click Me"><p id="text"></p>

现在我们要使

doThat
异步( 注意 :仅在支持
async
/ 的最新浏览器上才能使用
await
,例如Chrome;遗憾的是Stack
Snippet的Babel配置不包含它们,因此我们不能使用该选项):

var btn = document.getElementById("btn");btn.addEventListener("click", handler, false);// handler can't be asyncfunction handler(e) {  console.log("handler triggered");  doSomething();  console.log("handler done");}// doSomething can beasync function doSomething() {  doThis();  await doThat();  doTheOther();}function doThis() {  console.log("doThis - start & end");}// make doThat asyncasync function doThat() {  console.log("doThat - start");  // simulate beginning async operation with setTimeout  return new Promise(resolve => {    setTimeout(() => {      // do something that takes a while      var stop = Date.now() + 1000;      while (Date.now() < stop) {        // wait      }      console.log("doThat - end (async)");    }, 0);  });}function doTheOther() {  console.log("doThat - start & end");}.as-console.wrapper {  max-height: 80% !important;}<input type="button" id="btn" value="Click Me"><p id="text"></p>

关键是我们

doSomething
(因为
handler
不能异步)尽快进入异步状态。但是,当然,这改变了与处理程序有关的工作时间。(当然,我们可能应该进行更新,
handler
以捕获来自promise`doSomething()返回的错误。)


1这是Javascript规范术语。HTML5规范(也涉及到此规范)称它们为“任务”,而不是“工作”。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/4983839.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-11-14
下一篇2022-11-14

发表评论

登录后才能评论

评论列表(0条)

    保存