如何处理循环的异步操作

1,799 阅读1分钟

情景

假设有一个数组 需要 异步输出

const arr = [1, 2, 3, 4, 5];

function doAsync(time, cb) {
	if (cb) {
		setTimeout(cb, time);
	} else {
		return new Promise(resolve => {
			setTimeout(resolve, time);
		});
	}
}

function print(el) {
	return function() {
		console.log(el);
	};
}

all in 一次性做完所有异步

利用Promise.all
console.time("promise all in");
Promise.all(
	arr.map(item => {
		return doAsync(item * 100).then(print(`${item}-promise`));
	})
).then(() => {
	console.timeEnd("promise all in");
});
利用async/await
(async function() {
	console.time("async/await all in");
	for await (let i of arr.map(item => {
		return doAsync(item * 100).then(print(`${item}-async/await`));
	})) {
	}
	console.timeEnd("async/await all in");
})();

One by one 一次只做一个异步操作

利用Array.reduce
console.time("promise one by one");
arr.reduce((accumulator, currentValue, currentIndex) => {
	return accumulator.then(print(`${arr[currentIndex]}-Array.reduce`)).then(() => {
		if (currentIndex === arr.length - 1) {
			return doAsync(currentValue * 100).then(() => {
				console.timeEnd("promise one by one");
			});
		}
		return doAsync(currentValue * 100);
	});
}, doAsync(arr[0] * 100));
//吐槽 着实麻烦
async/await
(async function() {
	console.time("async/await one by one");
	for  (let item of arr) {
        await doAsync(item * 100).then(print(`${item}-async/await`));
	}
	console.timeEnd("async/await one by one");
})();