Combination of Async Function + Await + Settimeout

Combination of async function + await + setTimeout

Your sleep function does not work because setTimeout does not (yet?) return a promise that could be awaited. You will need to promisify it manually:

function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function sleep(fn, ...args) {
await timeout(3000);
return fn(...args);
}

Btw, to slow down your loop you probably don't want to use a sleep function that takes a callback and defers it like this. I recommend:

while (goOn) {
// other code
var [parents] = await Promise.all([
listFiles(nextPageToken).then(requestParents),
timeout(5000)
]);
// other code
}

which lets the computation of parents take at least 5 seconds.

Using a setTimeout in a async function

setTimeout() doesn't return a Promise, but you can wrap it in one like this. I also cleaned up the rest of your code a little.

async function processMatchingSchools(customer_metafield_url) {
for (const item of customer_metafield_url) {
await new Promise(resolve => {
setTimeout(resolve, 500)
})

await axios.get(item).then((res) => {
Object.values(res.data.metafields).filter(
({ value }) => value === schoolName
).forEach(({ owner_id }) => {
id_for_each_student.push(`${shopifyAdmin}/customers/${owner_id}/metafields.json`)
})
})
}

console.log("Customer metafields to search", id_for_each_student)

processOwnerIds(id_for_each_student)
}

await setTimeout is not synchronously waiting

setTimeout doesn't returns a Promise, so you can't await it.

You can wrap setTimeout in a function that returns a Promise which is fulfilled once the timer expires. You can await this wrapper function.

function createCustomTimeout(seconds) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('bla bla');
resolve();
}, seconds * 1000);
});
}

async function testing() {
console.log('testing function has been triggered');
await createCustomTimeout(4);
console.log('bla');
}

testing();

Continuous async/await with setTimeout

This is how you can achieve the desired output. You can wrap your setTimeout in a Promise and await it.

const test = async () => {

await new Promise((resolve)=>setTimeout(() => {

console.log("timeout");

resolve();

}, 2000));

console.log(1);

console.log(2);

}

test();

call Async function inside setTimeout

You shouldn't use setTimeout here: it will not execute the callback in parallel, but later, after the rest of the synchronous code has executed.

Instead, if it is the only asynchronous task that needs to happen before the call of res.status(200), then use await:

await updateWhOrders(req.Orders, req);

If you have more asynchronous tasks, and they are independent of each other such that they could execute in any order -- and don't have to wait for the other's result -- then use Promise.all:

await Promise.all([
updateWhOrders(req.Orders, req),
anotherAsyncFunc(),
yetAnotherAsyncFunc()
]);

Difference with setTimeout

You asked for the difference between these statements:

setTimeout(() => updateWhOrders(req.Orders, req), 0)
updateWhOrders(req.Orders, req)

The first will not call updateWhOrders now, but will schedule it for execution after all synchronous code has executed. This could be just after the next await has executed, or if there is none, after the return has executed. The call stack must become empty first and only then updateWhOrders can get executed.

The second will execute updateWhOrders immediately.

Neither use the fact that updateWhOrders returns a promise, and so this aspect is not well dealt with. You'll want to know when the asynchronous call inside updateWhOrders has finished its job, and for that you need to do something with the returned promise. That's why you should use either .then, await, Promise.all, ...or anything that deals with that promise.

SetTimeout for an async await function fo retrieve new data

hmm.. I would just make the setTimeout a Promise in itself and then have gas as an async function to call..

async function main() {
// get the current gwei prices & new price every 5 seconds

let gas = async () => {
return new Promise(r=>{
setTimeout(async()=>r(await getGas()),5e3);
})
}

console.log(await gas()); //whatever getGas should be

// other code down here

//whenever you want gas, you can just "await gas()"
}

However.. if you just didn't word your question correctly and you want the variable gas to be updated every 5 seconds in that block of code within recalling main

an async function to call..

async function main() {
// get the current gwei prices & new price every 5 seconds

let gas = null; //starting value
setInterval(async()=>gas=await getGas(),5e3); //every 5 seconds, gas is updated

console.log(gas); //null
setTimeout(()=>console.log(gas),6e3); //whatever getGas should be
// other code down here

//whenever you want gas, you can just "gas"
}

EDIT: you told me it doesn't work so I give a live example and am now asking how

async function getGas(){
return Math.floor(Math.random()*5)
}

async function main1() {
// get the current gwei prices & new price every 5 seconds

let gas = async () => {
return new Promise(r=>{
setTimeout(async()=>r(await getGas()), 5e3);
})
}

setInterval(async()=>
console.log(await gas(),"~ main1") //whatever getGas should be
,1e3);
// other code down here

//whenever you want gas, you can just "await gas()"
}

async function main2() {
// get the current gwei prices & new price every 5 seconds

let gas = null; //starting value
setInterval(async()=>gas=await getGas(),5e3); //every 5 seconds, gas is updated

console.log(gas); //null
setInterval(()=>
console.log(gas,"~ main2") //whatever getGas should be
,1e3);
// other code down here

//whenever you want gas, you can just "gas"
}
main1(); main2();


Related Topics



Leave a reply



Submit