Combination of async function + await + setTimeout
Your sleep
function does not work because setTimeout
does not (yet?) return a promise that could be await
ed. 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
Refresh Image With a New One At the Same Url
Parse Query String in JavaScript
How to Insert an Element After Another Element in JavaScript Without Using a Library
Node.Js - Syntaxerror: Unexpected Token Import
Using Jquery $(This) With Es6 Arrow Functions (Lexical This Binding)
How to Convert Decimal to Hexadecimal in JavaScript
How Does JavaScript Handle Ajax Responses in the Background
Check If a User Has Scrolled to the Bottom (Not Just the Window, But Any Element)
Query-String Encoding of a JavaScript Object
Is There a Cross-Browser Onload Event When Clicking the Back Button
Get the Name of an Object'S Type
JavaScript Open in a New Window, Not Tab
How to Get Hex Color Value Rather Than Rgb Value
Smooth Scrolling When Clicking an Anchor Link
Difference Between Object Keys With Quotes and Without Quotes
Difference Between ( For... in ) and ( For... of ) Statements