はじめに
JavaScriptでPromiseを直列接続しようとするとよくはまるので、メモしておく。
コメントも参照してね。
環境
- macOS High Sierra 10.13.5
- Node.js v8.11.3
ソースコード
'use strict'
function startPromise() {
return new Promise(resolve => {
console.log('START');
resolve();
});
}
function arrayPromise(array) {
array.forEach(element => {
setTimeout(() => {
console.log('ARRAY FINISH:' + element);
Promise.resolve();
}, element);
});
}
/**
* こいつはthenの中にfunctionじゃなくてPromiseを突っ込んでるのでうまくいかない。
* @param {*} array
*/
function badArrayPromise(array) {
// Promiseを保管する箱
var promiseArray = new Array();
// Promiseの生成
array.forEach(element => {
promiseArray.push(new Promise(resolve => {
console.log('ARRAY START:' + element);
setTimeout(() => {
console.log('ARRAY FINISH:' + element);
resolve();
}, element);
}));
});
// 直列接続
return promiseArray.reduce((p, c) => {
return p.then(c);
});
}
/**
* 正解
* @param {*} array
*/
function goodArrayPromise(array) {
// Functionを保管する箱
var functionArray = new Array();
// Promiseの生成
array.forEach(element => {
functionArray.push(() => {
return new Promise(resolve => {
console.log('ARRAY START:' + element);
setTimeout(() => {
console.log('ARRAY FINISH:' + element);
resolve();
}, element);
});
});
});
// 直列接続
return functionArray.reduce((p, c) => {
return p.then(c);
}, Promise.resolve());
}
function endPromise() {
return new Promise(resolve => {
console.log('END');
resolve();
});
}
function main() {
var ary = [1000,2000,3000,4000];
startPromise()
.then(() => {return goodArrayPromise(ary)})
.then(endPromise);
}
main();