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 everysleep()
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
4 Answers
Reset to default 4If 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);
}
}