在我的申请,我有和并行访问网络的承诺阵列,但有些时候,当我的应用程序正在运行全速,我的网络速度变慢,由于许多承诺访问网络,我想知道我怎么能控制如何许多并行的接入网络。 这是代码的示例:
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.all( Object.keys(ids).map(function(dp){
return new Promise(function(resolve, reject){
http.post({url: addr, form: { data: dp }}, function(err, res, body){
if (err){
reject(err)
}
resolve(body.xx);
});
});
})).then(function(data){
http.post({url: hostAddress, form: { data: data.x }}, function(err, res, body){
......
resolve(body.xx);
});
});
});
}))
有很多联网。 我将是巨大的,我可以只允许2或3在同一时间。 谢谢你的帮助。
您可以使用蓝鸟的.map()
具有并发选项来控制多少请求是在飞行的同时:
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
});
仅供参考,我不明白你试图用你的第二个做http.post()
因为你在哪里引用data.x
当data
是一个数组。 我觉得代码是有点过分的伪代码来说明你真的想与第二做http.post()
否则,你可以在这里你开始火起来了N个请求,然后每次一点结束编写自己的并发控制,你火了另一个,直到你有没有更多的工作要做。 下面是手动编码并发控制的示例:
火了一次1,000,000个要求100
或者,你可以把它写自己是这样的:
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
});
这是实现你的目标,而无需使用图书馆的一种方式。 内)从makeMaxConcurrencyRequests(返回的承诺,请startNew()函数的递归调用,发送新的请求,直到我们一直在通过每一个ID,并且不超过maxConcurrency的当前请求数。
当每个请求完成后,其返回数据被推入returnedData阵列。 当所有的请求都完成后,承诺与returnedData解决。
我没有测试过这一点,但看着它我唯一担心的是,startNew()是怎么回事,而请求正在等待以快速连续多次调用。 如果这导致问题,然后,而不是立即调用startNew(),我们可以使用的setTimeout来延迟下调用 - 这是在我的代码注释掉。
function makeMaxConcurrencyRequests(ids, maxConcurrency) {
return new Promise(function(resolve, reject) {
let i = 0, currentlyRunning = 0, returnedData = [];
function startNew() {
while (i < ids.length && currentlyRunning <= maxConcurrency) {
makeRequest(ids[i++]).then(function(data) {
returnedData.push(data);
currentlyRunning--;
startNew();
}).catch(function(err) {
reject(err);
});
currentlyRunning++;
}
if (i >= ids.length && currentlyRunning === 0) {
resolve(returnedData);
}
startNew();
// setTimeout(startNew, 200);
}
}
}
function makeRequest(id) {
return new Promise(function(resolve, reject){
http.post({url: addr, form: { data: dp }}, function(err, res, body){
if (err){
reject(err)
}
http.post({url: hostAddress, form: { data: body.xx }}, function(err2, res2, body2){
if(err2) {
reject(err2);
}
resolve(body2.xx);
});
});
});
}
用法:
var ids = {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 6: 56, 7: 7, 8: 8, 5:6 };
var maxConcurrency = 3;
makeMaxConcurrencyRequests(Object.keys(ids), maxConcurrency)
.then(function(data) {
// do something with data
}).catch(function(error) {
// do something with error
});