何をしたいの
JavaScript で wait をしたい。段階的に何かを表示するとかの演出に使うかもしれない。
setTimeout の入れ子とか、再帰的に書くのとかを回避するとか、Exponential Backoff したかったりする場合とかにも使える。
どう書くの
const wait = (msec)=>{
return new Promise((resolve)=>{
setTimeout(()=>{resolve(msec)}, msec);
});
};
どう使うの
素直に Promise を利用して次のように記述できる。
const waitBehavior1 = () => {
const before = Number(new Date());
wait(1250).then((waitLength) => {
const after = Number(new Date());
console.log(after - before);
});
};
ループで回したりするのには不便。
const LOOP_REQUEST_COUNT = 3;
const waitBehavior2 = (loopCount) => {
if(loopCount) {
wait(1250).then((waitLength) => {
console.log(`${LOOP_REQUEST_COUNT - loopCount + 1}週目`);
waitBehavior2(loopCount - 1);
});
} else {
console.log('おしまい');
}
};
waitBehavior2(LOOP_REQUEST_COUNT);
入れ子にしないで使う
本題。async と await に頼るといい感じに書ける。
const waitBehavior3 = async () => { // async を入れないとだめ
const before = Number(new Date());
await wait(1250); // ここも await を入れないとだめ
const after = Number(new Date());
console.log(after - before);
};
waitBehavior3();
これならループも簡単
const waitBehavior5 = async () => { // async を入れないとだめ
const before = Number(new Date());
for(let i = 0; i < 3; i++) {
await wait(1250); // ここも await を入れないとだめ
}
const after = Number(new Date());
console.log(after - before);
};
waitBehavior5();
ただ、以下のような使い方はできないので注意。
// ほぼ同時に ぱんだ、うさぎ、こあらが console.log される
waitBehavior6 = () => {
['ぱんだ', 'うさぎ', 'こあら'].forEach(async (animal)=>{
await wait(1250);
console.log(`${animal} ${Number(new Date())}`);
});
};