代码之家  ›  专栏  ›  技术社区  ›  ibodi

等待回调执行

  •  2
  • ibodi  · 技术社区  · 7 年前

    我想等到回拨结束。我试过这样的方法:

    let wait = true;
    setTimeout(() => {
        console.log("wait = false");
        wait = false;
    }, 2000);
    console.log("waiting");
    while(true) {
        if(!wait) break;
    }
    console.log("finished waiting");
    

    唯一的输出是

    waiting
    

    而且不会继续下去。即使“wait=false”在2秒后也不会打印。有人能解释为什么会这样吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   kiddorails    7 年前

    你的 while 循环不会让 setTimeout 跑。这是一个 同步的 无限循环逻辑,将阻塞js线程直到永远。

    设置超时 是一个异步方法,并在事件队列中注册自身。当主堆栈完成其工作时,事件循环检查队列中是否有挂起的工作,并将其带回主线程中。

    在你的情况下,主堆栈永远不会空闲,因为 虽然 循环永远不会完成。

    你可以使用 Promise 这样做。

    var promise = new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('timeout executed after 2s');
          resolve(); // resolve when setTimeout is done.
        }, 2000);
    });
    console.log('waiting');
    promise.then(_ => console.log("finished waiting")); // Use `.then` to do work after promise is resolved.

    或者你可以在 设置超时

    var callback = function() { 
      console.log('finished execution');
      // all other work.
    }
    
    console.log('waiting');
    setTimeout(callback, 2000);

    或使用 async-await . 这给人的印象是,逻辑是同步的,在前进之前等待承诺得到解决。

    (async function() {
      console.log('waiting')
      await new Promise((resolve, reject) => {
        setTimeout(_ => {
          console.log('setTimeout executed');
          resolve();
        }, 2000)
      })
      console.log('finished execution')
    })()