编辑:这适用于Electron项目,本地服务器在用户系统上启动。因此,如果多个用户尝试同时访问会发生什么问题,可以忽略任何问题!
我的客户端代码正在生成一个JavaScript对象数组,我正在调用数据包。可能存在无限的数据包,但1到10之间是最常见的用例。
我需要对后端路由进行API调用,每个数据包一次,将数据包作为参数传递给每个调用。
但是,后端会对每个数据包执行一些重度计算工作,以至于尝试同时处理超过2-3个数据包会导致服务器崩溃。< / p>
是否可以同步解析 Promises ,以便第二个 Promise 仅在第一个解析时触发,第三个触发在第二个之后触发,依此类推?
我的理解是 Promise.all()同时拨打所有电话,这对我没有帮助。
(我也知道这是一种反模式,但根据我的具体要求,我不知道还能做什么)
我知道这纯粹是抽象的,但任何想法都会受到赞赏!!!
答案 0 :(得分:3)
异步队列,是我previous answers的衍生队列;我已经添加了随机完成时间来模拟真实环境:
class Queue {
constructor() {
this.queue = [];
}
enqueue(obj) {
return this.queue.push(obj);
}
dequeue() {
return this.queue.shift();
}
hasWork() {
return (this.queue.length > 0);
}
}
class AsyncQueue extends Queue {
constructor(job) {
super();
this.job = job;
}
process(cb) {
return this.job(this.dequeue()).then(data => {
cb(data);
if (this.hasWork())
return this.process(cb);
});
}
}
//MUST RETURN Promise
function work() {
var duration = chooseDelay();
console.log('START JOB, I.E., MAKE REQUEST (will take %s)', duration);
return t_o(duration);
}
function report() {
console.log('JOB DONE');
}
function done() {
console.log('ALL WORK DONE');
}
function t_o(delay) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();
}, delay);
});
}
function chooseDelay() {
var delays = [200, 1000, 4000, 100, 50, 7000];
return delays[parseInt(Math.random() * 100) % delays.length];
}
var q = new AsyncQueue(work);
for (var packet = 0; packet < 10; ++packet)
q.enqueue(packet);
q.process(report).then(done);
&#13;
答案 1 :(得分:1)
作为另一个好的答案的替代方案,这里有一个非常简单的队列(work
函数可以无耻地复制并从其他答案中扩展)
// Here is the queue "creator"
let promiseQueue = fn => {
let q = Promise.resolve();
return (...args) => q = q.then(() => fn(...args));
};
// that's it, that's the whole code for a promise queue
// here we create a queue
var q = promiseQueue(work);
// simple mock asynchronous function
function work({index, data}) {
var duration = parseInt(Math.random() * 100) + 100;
console.log('START JOB %s, I.E., MAKE REQUEST (will take %s) and should result with %s', index, duration, (index +1) * data);
return new Promise(resolve => setTimeout(resolve, duration)) // mock a delay
.then(() => ({index, result:(index + 1) * data})); // and some "processing"
}
// simulating two "chunks" of packets, generated a millisecond apart, but still, the sequence will be maintained
setTimeout(() => {
var packets = Array.from({length:10}, (_, index) => ({index, data:parseInt(Math.random() * 10000)}));
var promises = packets.map(packet => q(packet));
// the results in promise all are all the results of this batch of "packets"
Promise.all(promises).then(results => console.log(results));
}, 100);
setTimeout(() => {
var packets = Array.from({length:10}, (_, index) => ({index: index + 10, data:parseInt(Math.random() * 10000)}));
var promises = packets.map(packet => q(packet));
Promise.all(promises).then(results => console.log(results));
}, 101);
答案 2 :(得分:1)
顺序执行promises的简单函数
snprintf(buf, sizeof(buf), "<LONG PROCESS WITH PARAMETERS HAVING SENSITIVE INFO>";
system(buf);
答案 3 :(得分:1)
'use strict';
// job to be done
function job(params) {
return function () {
console.log('job started', params);
return new Promise(function (resolve) {
setTimeout(function () {
console.log('job finished');
resolve();
}, 1000);
})
}
}
// data to be processed sequentially
var params = [
1,
2,
3,
4,
5
];
// reduce data to Promise sequence
params.reduce(function (cum, cur) {
return cum.then(job(cur));
}, Promise.resolve());
答案 4 :(得分:0)
使用async / await变得微不足道:
while (promiseArray.length > 0)
await promiseArray.shift();