最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is there a way to call sleep() without await keyword? - Stack Overflow

programmeradmin1浏览0评论

I want to call sleep() function without the await keyword before it. To achieve this, I tried with another wrapper-async function sleepAsync(x, callback) with callback but it didn't work.

Here is my code -

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));
}

Now the function call where it works correctly -

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

fcall(4);

In the above way of calling, each iteration waits for 2 sec before continuing.

Below code is where sleep() doesn't wait for 2 sec -

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);

What can be done here? and where am I making mistake?

I want to call sleep() function without the await keyword before it. To achieve this, I tried with another wrapper-async function sleepAsync(x, callback) with callback but it didn't work.

Here is my code -

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));
}

Now the function call where it works correctly -

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

fcall(4);

In the above way of calling, each iteration waits for 2 sec before continuing.

Below code is where sleep() doesn't wait for 2 sec -

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);

What can be done here? and where am I making mistake?

Share Improve this question asked Nov 29, 2019 at 6:00 azashiazashi 811 silver badge8 bronze badges 6
  • Sleep is not a part of JS program design, what do you want to achieve? – Teemu Commented Nov 29, 2019 at 6:03
  • 2 If you want to do sleep each tick of a loop without the async keyword, I think you might have to refactor it to a recursive function. But the question is why. – max pleaner Commented Nov 29, 2019 at 6:04
  • I want to pause execution for certain seconds and then resume back. So, how can I make it happen without writing await before every sleep() call. – azashi Commented Nov 29, 2019 at 6:07
  • Regarding the question of why I would want to do that, the answer is - curiosity. I am kind of new to JS and was wondering, is there a way, hence the question. – azashi Commented Nov 29, 2019 at 6:11
  • async / await can be transpiled to make it work on browsers that don't support this syntax, so yes there is a way. If you want to make it work on older browsers, then the answer is "use a transpiler", if you really wish to learn how it could be rewritten by hand, then try to do it, and e back here if you face an issue while trying to do it. – Kaiido Commented Nov 29, 2019 at 6:13
 |  Show 1 more ment

4 Answers 4

Reset to default 4

If you don't want to use an external package, and async won't work for reasons, the sleep package now remends using the built-in Atomics.wait (which is included in node after node 9.3), like so:

function msleep(n) {
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, n);
}
function sleep(n) {
  msleep(n*1000);
}

I've used this successfully in production.

Source: sleep

An async function will not work at the exact time if the rest of the code after is not waiting for it.

When codes start running each statement will be added to a queue and the runner will start reading using that queue. An async funtion will be added to the end of the queue.

Assume this code:

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

The queue to be executed can be like this:

let a
doSomething
doSomething2
doSomethingAsync

But of you use await the async code will be added to that position where you invoked it. So adding await doSomethingAsync(); will make the queue like this:

let a
doSomthing
doSomethingAsync
doSomething2

TL; DR

You use await when you want the code to be executed now, not put it at the queue.

You can try sleep package from npm, see it at https://www.npmjs./package/sleep.

JS has a run to pletion guarantee, so if you call color() it is guaranteed to run pletely There is no way to halt the execution of it in any way. There are however async functions and generator functions that can be run piecewise (meaning: till an await or yield is reached), so if you don't want to use await, you have to 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);
     }
 }
发布评论

评论列表(0)

  1. 暂无评论