我使用Node.js已有5年的历史,从2年开始使用这个框架的大型项目。两年来,我遇到了一个问题:如何使用非异步第三方应用程序(如MySQL,MongoDB或Apache SolR)异步和快速地工作?
我曾经使用过承诺并准备了几个承诺请求,如下所示:
const promises = []
for (let i = 0; i < 1000; i += 1) {
const promise = mySqlRequest()
promises.push(promise)
}
Promise.all(promises)
.then()
.catch()
这个例子可以工作,但会同时向MySQL服务器发送1000个请求,他们会堆叠这些请求并变得非常慢,会消耗非常大量的RAM。
最好的解决方案是只做一个大的请求,但在某些情况下它是不可能的,我被迫做出递归函数, 归结为同步和慢。
那么,使用Node.js和堆叠第三方快速和异步工作的最佳方法是什么?
答案 0 :(得分:1)
如果一次发送所有请求不起作用并且逐个发送它们也不起作用,则需要类似于线程池的内容,其中一些任意数量的任务同时执行。这很容易使用promises实现,例如:
Promise.pooled = function(arr, num = 5) {
return new Promise(function(resolve, reject) {
var i = -1;
var error = false;
var end = function() {
num--;
if(num === 0) resolve();
}
var next = function() {
if(error) return;
i++;
if(i >= arr.length)
end();
else
arr[i]().then(next).catch(onerr);
}
var onerr = function() {
if(error) return
error = true
reject.call(arguments)
}
for(var j = 0; j < num; j++)
next()
});
}
这允许你传递一个数组的函数作为第一个参数,这些函数应该不带参数并返回一个promise。然后它将同时执行num
。如果其中一个承诺失败,它将失败自己的承诺并停止执行(这很容易改变)。
示例:
Promise.after = function(ms) {
return new Promise(function(resolve) {
setTimeout(resolve, ms)
});
}
Promise.pooled = function(arr, num = 5) {
return new Promise(function(resolve, reject) {
var i = -1;
var error = false;
var end = function() {
num--;
if(num === 0) resolve();
}
var next = function() {
if(error) return;
i++;
if(i >= arr.length)
end();
else
arr[i]().then(next).catch(onerr);
}
var onerr = function() {
if(error) return
error = true
reject.call(arguments)
}
for(var j = 0; j < num; j++)
next()
});
}
var test = [
afterH(1000),
afterH(500),
afterH(800),
afterH(600),
afterH(3000),
afterH(300),
afterH(900),
afterH(2000),
afterH(1500),
afterH(900),
afterH(700),
afterH(600),
afterH(700)
];
// helper function, returns a function which when invoked returns a promise
function afterH(ms) {
return function() {
console.log("Starting one job")
return Promise.after(ms);
}
}
Promise.pooled(test, 3).then(function() {console.log("All jobs finished") }).catch(function() {console.log("Job failed")})