AWS lambda で Node.js と向きう合う必要が出てきたので、最近のモダンな JS を理解する
最近は async/await が使えるらしいが、内部的には Promise を使っているらしいので、まずは Promise から理解する
Promise とは?
非同期処理の実行結果(成功 or 失敗) の受け取り口を用意して、非同期の管理を容易にするためのオブジェクト
コールバック地獄のしんどさを回避するために生まれた
つかいかた
new Promise
する
- 第一引数は、引数が2つある関数
- 関数の第1引数には、正常終了時に呼び出す関数
- 関数の第2引数には、異常終了時に呼び出す関数
new Promise
の戻り値は、then()
と catch()
を持つオブジェクト
then()
か catch()
が呼ばれた時点で、promise に渡した関数が実行される
正常終了例
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('foo');
}, 10);
});
promise.then((value) => {
console.log("then");
console.log(value);
}).catch((value) => {
console.log("catch");
console.log(value);
});
出力結果
then
foo
異常終了例
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject('foo');
}, 10);
});
promise.then((value) => {
console.log("then");
console.log(value);
}).catch((value) => {
console.log("catch");
console.log(value);
});
出力結果
catch
foo
Promise のチェーン
then()
の戻り値を Promise
オブジェクトにすることで、Promise をチェーンできる
これにより、非同期処理を同期的に実行できる
例
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('promise1');
}, 10);
});
promise1.then((value) => {
console.log("then 1");
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('promise2');
}, 10);
});
}).then((value) => {
console.log("then 2");
});
出力結果
then 1
then 2
Promise#all
複数 Promise の並列実行ができる
正常終了例
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('promise1')
resolve('promise1');
}, 10);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('promise2')
resolve('promise2');
}, 10);
});
Promise.all([
promise1, promise2
]).then((value) => {
console.log(value)
console.log('finished')
});
then()
には、各 Promise
の resolve
の引数を配列にしたものが渡される
promise1
promise2
[ 'promise1', 'promise2' ]
finished
異常終了例
1つでも reject()
が呼ばれたら catch()
が呼ばれる
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('promise1');
}, 10);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('promise2');
}, 10);
});
Promise.all([
promise1, promise2
]).then((value) => {
console.log(value)
console.log('finished')
}).catch((value) => {
console.log(value)
console.log('catch')
});
出力結果
promise2
catch
reject()
が複数発生する場合も、早いもの勝ちで最初の reject()
の引数が渡される
処理自体は最後まで行われる
Promise.race()
複数 Promise のうち、1つでも処理が完了したら then()
が呼ばれる