【问题标题】:Is there a way to call sleep() without await keyword?有没有办法在没有 await 关键字的情况下调用 sleep() ?
【发布时间】:2019-11-29 14:41:10
【问题描述】:

我想在没有await 关键字的情况下调用sleep() 函数。为了实现这一点,我尝试了另一个 wrapper-async 函数 sleepAsync(x, callback) 与回调,但它没有工作。

这是我的代码 -

function color() {
  let string1 = "yellow yeelow";
  console.log(string1);
  let string2 = "blu glu";
  console.log(string2);
  let string3 = "green freen";
  console.log(string3);
}

async function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms * 1000));
}

现在是正常工作的函数调用 -

async function fcall(loop = 2) {
  for (let x = loop; x > 0; x--) {
    color();
    await sleep(2);
  }
}

fcall(4);

上述调用方式,每次迭代等待2秒再继续。

下面的代码是 sleep() 不等待 2 秒的地方 -

async function sleepAsync(x, callback) {
    callback();
    await sleep(x);
  }

  function gcall(loop = 2) {
    for (let x = loop; x > 0; x--) {
      sleepAsync(2, color);
    }
  }

  gcall(4);

这里可以做什么?我在哪里犯错了?

【问题讨论】:

  • 睡眠不是JS程序设计的一部分,你想实现什么?
  • 如果您想在循环的每个滴答声没有 async 关键字的情况下进行睡眠,我认为您可能必须将其重构为递归函数。但问题是为什么。
  • 我想暂停执行几秒钟然后恢复。那么,如何在每次sleep() 调用之前不写await 来实现它。
  • 关于我为什么要这样做的问题,答案是——好奇。我对 JS 有点陌生,我想知道,有没有办法,所以这个问题。
  • async / await 可以被转译以使其在不支持此语法的浏览器上工作,所以是的,有一种方法。如果你想让它在旧版浏览器上运行,那么答案是“使用转译器”,如果你真的想学习如何手动重写它,那么试着去做,如果你遇到问题再回到这里在尝试这样做时。

标签: javascript node.js asynchronous async-await


【解决方案1】:

如果之后的其余代码没有等待异步函数,则该函数将不会在确切的时间工作。

当代码开始运行时,每条语句都会被添加到一个队列中,运行器将开始使用该队列进行读取。一个异步函数将被添加到队列的末尾。

假设这段代码:

let a = true;
doSomething();
doSomethingAsync();
doSomething2();

要执行的队列可以是这样的:

let a
doSomething
doSomething2
doSomethingAsync

但是你们使用await,异步代码将被添加到你调用它的位置。所以添加await doSomethingAsync(); 会使队列变成这样:

let a
doSomthing
doSomethingAsync
doSomething2

TL;博士

当你希望代码现在被执行时,你使用await,而不是把它放在队列中。

【讨论】:

  • 好的,明白了。谢谢。所以我想我将不得不使用等待。没有别的办法..
【解决方案2】:

您可以从 npm 尝试 sleep 包,请参阅 https://www.npmjs.com/package/sleep

【讨论】:

  • 谢谢,但我实际上是在寻找不依赖于该软件包的解决方案。比如一些代码更改之类的。
  • 您可以尝试使用child_process.execSynctimeout 选项,例如:typescript function sleep(timeout) { try { child_process.execSync(`sleep ${Math.ceil(timeout / 1e3)}`, { timeout }) } catch { return } }
【解决方案3】:

JS 有一个运行到完成保证,所以如果你调用color() 它保证完全运行 没有办法以任何方式停止它的执行。但是有 async 函数generator 函数 可以分段运行(意思是:直到达到 awaityield),所以如果你不想要要使用await,你必须yield

 function* color() {
   let string1 = "yellow yeelow";
   console.log(string1);
   yield;

   let string2 = "blu glu";
   console.log(string2);
    yield;

    let string3 = "green freen";
    console.log(string3);
  }

  async function sleep(ms) {
     return new Promise(resolve => setTimeout(resolve,  ms * 1000));
  }


  async function fcall() {
     const it = color();
     let done = false;
     while(!done) {
       ({ done } = it.next());
       await sleep(2);
     }
 }

【讨论】:

  • 我没想过以那种方式使用yield。谢谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-10
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
  • 2011-06-04
  • 1970-01-01
相关资源
最近更新 更多