Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making the while loop synchronous

I've got a following piece of code

var page = 2; var last_page = 100; while(page <= last_page) {   request("http://some_json_server.com/data?page=" + page, function (error, response, body) {     if (!error && response.statusCode == 200) {       store_data(body)     }     page++;   });                 } 

I've done the following, but it is actually not retrieving anything. Am I doing this correctly?

var page = 2; var last_page = 100; while(page <= last_page) { var async_arr = []; async_arr.push(   function(next) {     request("http://some_api_url?page=" + page, function (error, response, body) {       if (!error && response.statusCode == 200) {         store_data(body);       }     });   } );  async.series(   async_arr, done ); 
like image 422
ericbae Avatar asked Apr 09 '13 12:04

ericbae


People also ask

Is while loop asynchronous?

Just like the for loop, the JavaScript while loop can use async/await too. In the following implementation we treat the corresponding array like a queue. We dequeue the element at index 0 of the array during each loop iteration. By the time the while loop is done executing, the array is empty.

Is a for loop synchronous?

for loop is synchronous. B should not be executed before for loop completes.

Can you use await in a while loop?

You need to place the loop in an async function, then you can use await and the loop stops the iteration until the promise we're awaiting resolves. You could also use while or do.. while or for loops too with this same structure. But you can't await with Array.

Is forEach synchronous?

Note: forEach expects a synchronous function. forEach does not wait for promises. Make sure you are aware of the implications while using promises (or async functions) as forEach callback.


2 Answers

With while you get a busy loop, which is counter-purpose in Node.

Make it a recursive function instead. Each call will be done in a separate tick.

var page = 2; var last_page = 100;  (function loop() {     if (page <= last_page) {         request("/data?page=" + page, function (error, response, body) {             if (!error && response.statusCode == 200) {                 store_data(body)             }             page++;             loop();         });     } }()); 
like image 159
katspaugh Avatar answered Sep 19 '22 03:09

katspaugh


You're looking for async.whilst(). This solution is assuming you actually want to do each request after the other. As @UpTheCreek mentions (edit: the comment I referred to was edited) it would likely be possible to do it asynchronously and keep track of each result using async.parallel.

var page = 2,     lastPage = 100;  async.whilst(function () {   return page <= lastPage; }, function (next) {   request("http://some_json_server.com/data?page=" + page, function (error, response, body) {     if (!error && response.statusCode == 200) {       store_data(body)     }     page++;     next();   }); }, function (err) {   // All things are done! }); 
like image 36
Andreas Hultgren Avatar answered Sep 17 '22 03:09

Andreas Hultgren