Async functionを使うとポーリングがループで書けて便利だったので共有します。
下記のようにサーバーサイドでバックグラウンド処理が完了したら次の画面に遷移する、というような状況で、wait
って関数でポーリングすると想定してください。
startBackgroundProcessing();
wait().then(() => {
moveToNextScreen();
});
まずヘルパー関数を定義します。Promise版setTimeout
と、ポーリング先のAPIを叩く関数です。
const sleep = (n) => new Promise(resolve => setTimeout(resolve, n));
const isProcessing = async (id) => {
const {processed} = await new Promise((resolve, reject) => $.ajax({
type: 'GET',
url: '/api/v1/somewhere',
dataType : 'JSON',
success: resolve,
error: reject
}));
return !processed;
};
Async functionを使わない場合のwait
の実装例。継続渡しになって補助関数を定義しないといけないし、難しいです。
const waitWithContinuation = (id, cont) =>
sleep(POLLING_INTERVAL).then(() =>
isProcessing(id).then(processed => {
if (processed) {
cont();
} else {
waitWithContinuation(id, cont);
}
})
);
const wait = (id) => new Promise(resolve => waitWithContinuation(id, resolve));
Async functionを使う場合。簡潔に書けました。
const wait = async (id) => {
while (await isProcessing(id)) {
await sleep(POLLING_INTERVAL);
}
};
エラー処理は省略しています。