Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combination of async function + await + setTimeout

I am trying to use the new async features and I hope solving my problem will help others in the future. This is my code which is working:

  async function asyncGenerator() {     // other code     while (goOn) {       // other code       var fileList = await listFiles(nextPageToken);       var parents = await requestParents(fileList);       // other code     }     // other code   }    function listFiles(token) {     return gapi.client.drive.files.list({       'maxResults': sizeResults,       'pageToken': token,       'q': query     });   } 

The problem is, that my while loop runs too fast and the script sends too many requests per second to the google API. Therefore I would like to build a sleep function which delays the request. Thus I could also use this function to delay other requests. If there is another way to delay the request, please let me know.

Anyway, this is my new code which does not work. The response of the request is returned to the anonymous async function within the setTimeout, but I just do not know how I can return the response to the sleep function resp. to the initial asyncGenerator function.

  async function asyncGenerator() {     // other code     while (goOn) {       // other code       var fileList = await sleep(listFiles, nextPageToken);       var parents = await requestParents(fileList);       // other code     }     // other code   }    function listFiles(token) {     return gapi.client.drive.files.list({       'maxResults': sizeResults,       'pageToken': token,       'q': query     });   }    async function sleep(fn, par) {     return await setTimeout(async function() {       await fn(par);     }, 3000, fn, par);   } 

I have already tried some options: storing the response in a global variable and return it from the sleep function, callback within the anonymous function, etc.

like image 640
JShinigami Avatar asked Oct 22 '15 20:10

JShinigami


People also ask

Can you mix promises and async await?

Async/Await is a fancier syntax to handle multiple promises in synchronous code fashion. When we put async keyword before a function declaration, it will return a promise and we can use await keyword inside it which blocks the code until promise it awaits resolves or rejects.

Can one async function have multiple awaits?

In order to run multiple async/await calls in parallel, all we need to do is add the calls to an array, and then pass that array as an argument to Promise. all() . Promise. all() will wait for all the provided async calls to be resolved before it carries on(see Conclusion for caveat).

Can we use async await with setTimeout?

With the help of Node. js development team, we are now able to use async/await syntax while dealing with setTimeout() functions. This feature was initially implemented in Node v.

How do you make asynchronous setTimeout?

export const asyncTimeout = (ms: number) => { return new Promise((resolve) => { setTimeout(resolve, ms); }); }; A simple function, that simply takes in the amount of milliseconds you wish to wait as a parameter. We then immediately return a new Promise, which is resolved when setTimeout completes.


1 Answers

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.

like image 149
Bergi Avatar answered Oct 05 '22 01:10

Bergi