Nodejs Synchronous For each loop

后端 未结 6 1560
刺人心
刺人心 2020-12-28 15:51

I want to do a for each loop but have it run synchronously. Each iteration of the loop will do an http.get call and that will return json for it to insert the values into a

相关标签:
6条回答
  • "use strict";
    
    var Promise = require("bluebird");
    var some = require('promise-sequence/lib/some');
    
    var pinger = function(wht) {
        return new Promise(function(resolve, reject) {
            setTimeout(function () { 
    
                console.log('I`ll Be Waiting: ' + wht);
                resolve(wht);
    
            }, Math.random() * (2000 - 1500) + 1500);
        });
    }
    
    var result = [];
    for (var i = 0; i <= 12; i++) {
        result.push(i);
    }
    
    some(result, pinger).then(function(result){
      console.log(result);
    });
    
    0 讨论(0)
  • 2020-12-28 16:17

    I found out that I wasn't releasing my mysql connections after I was done with each call and this tied up the connections causing it to fail and appear to be an issue with synchronization.

    After explicitly calling connection.release(); it caused my code to work 100% correctly even in an asynchronous fashion.

    Thanks for those who posted to this question.

    0 讨论(0)
  • 2020-12-28 16:23

    To loop and synchronously chain asynchronous actions, the cleanest solution is probably to use a promise library (promises are being introduced in ES6, this is the way to go).

    Using Bluebird, this could be

    Var p = Promise.resolve();
    forEach(sets, function(item, index, arr) {
        p.then(new Promise(function(resolve, reject) {
             http.get(theUrl, function(res) {
             ....
             res.on('end', function() {
                  ...
                  resolve();
             }
        }));
    });
    p.then(function(){
       // all tasks launched in the loop are finished
    });
    
    0 讨论(0)
  • 2020-12-28 16:23
    var urls = ['http://stackoverflow.com/', 'http://security.stackexchange.com/', 'http://unix.stackexchange.com/'];
    
    for (i = 0; i < urls.length; i++){
       http.get(urls[i], function(res) {
           // add some code here to process the response
       });
    }
    
    0 讨论(0)
  • 2020-12-28 16:30

    With recursion the code is pretty clean. Wait for the http response to come back then fire off next attempt. This will work in all versions of node.

    var urls = ['http://stackoverflow.com/', 'http://security.stackexchange.com/', 'http://unix.stackexchange.com/'];
    
    var processItems = function(x){
      if( x < urls.length ) {
        http.get(urls[x], function(res) {
    
          // add some code here to process the response
    
          processItems(x+1);
        });
      }
    };
    
    processItems(0);
    

    A solution using promises would also work well, and is more terse. For example, if you have a version of get that returns a promise and Node v7.6+, you could write an async/await function like this example, which uses some new JS features.

    const urls = ['http://stackoverflow.com/', 'http://security.stackexchange.com/', 'http://unix.stackexchange.com/'];
    
    async function processItems(urls){
      for(const url of urls) {
        const response = await promisifiedHttpGet(url);    
        // add some code here to process the response.
      }
    };
    
    processItems(urls);
    

    Note: both of these examples skip over error handling, but you should probably have that in a production app.

    0 讨论(0)
  • 2020-12-28 16:31

    Just wrap the loop in an async function. This example illustrates what I mean:

    const oneSecond = async () => 
        new Promise((res, _) => setTimeout(res, 1000));
    

    This function completes after just 1 second:

    const syncFun = () => {
        for (let i = 0; i < 5; i++) {
            oneSecond().then(() => console.log(`${i}`));
        }
    }
    
    syncFun(); // Completes after 1 second ❌
    

    This one works as expected, finishing after 5 seconds:

    const asyncFun = async () => {
        for (let i = 0; i < 5; i++) {
            await oneSecond();
            console.log(`${i}`);
        }
    }
    
    asyncFun(); // Completes after 5 seconds ✅
    
    0 讨论(0)
提交回复
热议问题