美文网首页
😀Promise并发控制

😀Promise并发控制

作者: 带马界的神秘人 | 来源:发表于2018-03-16 23:34 被阅读0次

    当需要查询1000w个url的时候,想多线程发送,但是不想同时一次性查询。

    🕒 一次性查询

    var http = require("http");
     
    var totalUrl = 10000000;
    for( var i = 0; i < totalUrl; i++ ) {
        getUrl(i);
    }
     
     
    function getUrl(idToFetch){
     
        var options = {
          host: 'www.mywebsite.com',
          port: 80,
          path: '/page.php?id='+idToFetch,
          agent: false,
          pageId: idToFetch
        };
     
        http.get(options, function(res) {
            var pageData = "";
     
            res.resume();
            res.on('data', function (chunk) {
                if(res.statusCode == 200){
                    pageData +=chunk;
                }
            });
     
            res.on('end', function() {
                console.log("finish to fetch id: "+options.pageId);
                // do something with the HTML page
            });
     
        }).on('error', function(e) {
           console.log("Error: " + options.host + "\n" + e.message);
        });
    }
    

    🚀控制promise并发

    Promise.race可以接收一个promise数组并,在其中第一个promise返回的时候返回。通过这个我们就可以控制并发的promise数量。

    /**
     * promise 并发处理 控制最大请求数
     * @param factory promise工厂 返回非Promise对象表示结束
     * @param maxRun  最大并发数
     * @param promises promise数组 缓存正在运行的promise
     * @param startIndex 开始的索引 默认从0 开始
     * @returns {Promise}
     */
    function promiseMax(factory, maxRun, promises, startIndex) {
        if (!Array.isArray(promises)) {
            promises = [];
        }
        if (startIndex === undefined) {
            startIndex = 0;
        }
        while (promises.length < maxRun) {
            let pro = factory(startIndex++);
            if (pro instanceof Promise) {
                pro = pro.then(v => {
                    promises.splice(promises.indexOf(pro), 1);
                    return v;
                });
                promises.push(pro);
            } else {
                return Promise.all(promises);
            }
        }
        return Promise.race(promises).then(() => {
            return promiseMax(factory, maxRun, promises, startIndex)
        });
    }
    

    ✈️并发请求

    通过promiseMax第二个参数可以很容易控制并发数量。

    promiseMax((idToFetch) => {
        if (idToFetch >= 10000000) return false;
        return new Promise((resolve, reject) => {
            var options = {
                host: 'www.mywebsite.com',
                port: 80,
                path: '/page.php?id=' + idToFetch,
                agent: false,
                pageId: idToFetch
            };
    
            http.get(options, function (res) {
                var pageData = "";
    
                res.resume();
                res.on('data', function (chunk) {
                    if (res.statusCode == 200) {
                        pageData += chunk;
                    }
                });
    
                res.on('end', function () {
                    console.log("finish to fetch id: " + options.pageId);
                    resolve();
                });
    
            }).on('error', function (e) {
                console.log("Error: " + options.host + "\n" + e.message);
                reject(e);
            });
        });
    }, 10).then(() => {
        console.info('end');
    });
    

    相关文章

      网友评论

          本文标题:😀Promise并发控制

          本文链接:https://www.haomeiwen.com/subject/vghdqftx.html