Javascript - how to control how many promises access network in parallel

前端 未结 2 476
天涯浪人
天涯浪人 2020-11-27 23:32

in my application, I have and array of promises that access network in parallel, but some times, when my app is running full speed, my network slows down, due to many promi

2条回答
  •  粉色の甜心
    2020-11-28 00:23

    You can use Bluebird's .map() which has a concurrency option to control how many requests are in-flight at the same time:

    const Promise = require('bluebird');
    const http = Promise.promisifyAll(require('http');
    
    var ids = {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 6: 56, 7: 7, 8: 8, 5:6 }; // this is random 
    
    Promise.map(Object.keys(ids).map(function(dp){
        return  http.post({url: addr, form: { data: dp }).then(function(body) {
            return body.xx;
        });
    }), {concurrency: 2}).then(function(results) {
        // process results here
    });
    

    FYI, I didn't understand what you were trying to do with your second http.post() because you where referencing data.x when data is an array. I think the code is a bit too much pseudo-code to illustrate what you were really trying to do with that second http.post().


    Otherwise, you can code your own concurrency control where you fire up N requests initially and then each time one finishes, you fire up another until you have no more to do. Here's an example of coding the concurrency control manually:

    Fire off 1,000,000 requests 100 at a time

    Or, you could write it yourself like this:

    const http = require('http');
    
    function httpPost(options) {
        return new Promise(function(resolve, reject) {
            http.post(options, function(err, res, body) {
                if (err) {
                    reject(err);
                } else {
                    resolve(body);
                }
            });
        });
    }
    
    // takes an array of items and a function that returns a promise
    function mapConcurrent(items, maxConcurrent, fn) {
        let index = 0;
        let inFlightCntr = 0;
        let doneCntr = 0;
        let results = new Array(items.length);
        let stop = false;
    
        return new Promise(function(resolve, reject) {
    
            function runNext() {
                let i = index;
                ++inFlightCntr;
                fn(items[index], index++).then(function(val) {
                    ++doneCntr;
                    --inFlightCntr;
                    results[i] = val;
                    run();
                }, function(err) {
                    // set flag so we don't launch any more requests
                    stop = true;
                    reject(err);
                });
            }
    
            function run() {
                // launch as many as we're allowed to
                while (!stop && inflightCntr < maxConcurrent && index < items.length) {
                    runNext();
                }
                // if all are done, then resolve parent promise with results
                if (doneCntr === items.length) {
                    resolve(results);
                }
            }
    
            run();
        });
    }
    
    var ids = {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 6: 56, 7: 7, 8: 8, 5:6 }; // this is random 
    
    
    mapConcurrent(Object.keys(ids), 2, function(item, index) {
        return httpPost({url: addr, form: {data: item}}).then(function(body) {
            return body.xxx;
        });
    }).then(function(results) {
        // array of results here
    }, function(err) {
        // error here    
    });
    

提交回复
热议问题