顺序解决Promises

时间:2017-10-31 23:09:00

标签: javascript asynchronous promise

编辑:这适用于Electron项目,本地服务器在用户系统上启动。因此,如果多个用户尝试同时访问会发生什么问题,可以忽略任何问题!

我的客户端代码正在生成一个JavaScript对象数组,我正在调用数据包。可能存在无限的数据包,但1到10之间是最常见的用例。

我需要对后端路由进行API调用,每个数据包一次,将数据包作为参数传递给每个调用。

但是,后端会对每个数据包执行一些重度计算工作,以至于尝试同时处理超过2-3个数据包会导致服务器崩溃。< / p>

是否可以同步解析 Promises ,以便第二个 Promise 仅在第一个解析时触发,第三个触发在第二个之后触发,依此类推?

我的理解是 Promise.all()同时拨打所有电话,这对我没有帮助。

(我也知道这是一种反模式,但根据我的具体要求,我不知道还能做什么)

我知道这纯粹是抽象的,但任何想法都会受到赞赏!!!

5 个答案:

答案 0 :(得分:3)

对Promises

感到奇怪

异步队列,是我previous answers的衍生队列;我已经添加了随机完成时间来模拟真实环境:

&#13;
&#13;
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;
&#13;
&#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();