#はじめに
最近Chrome拡張機能を作ろうと、JavaScriptを触り始めました。
漏れなく非同期処理というものにハマったので、繰り返し処理でPromiseしたいという初心者向けの覚書です。
Promiseやasync/awaitに関しては素晴らしい記事がたくさんあるので、Google itしてください。
#細かいお話
今回私がやりたかったのは、クローリングを自動化するChrome拡張機能を作成することです。
これにあたって、以下の作業を同期的に繰り返し行う必要があります。
- ページをクロール
- 結果が取れているか確認
- 次のページへ
- ページのロードが完了したら1へ
ことChrome拡張機能においては特に、クローリングやページロードは全て非同期的に行われるのが
めちゃくちゃ厄介でした。
Javascript初心者だったので、はじめはなぜ結果が戻ってこないのかすらわからない。
promiseやasync/awaitを覚えたところで、繰り返し処理の中にどうやって使うの・・・?
て感じで四苦八苦しましたが、まあ割と簡単に簡潔に書けたみたいです。
#書いたコード
煩雑になるので中の処理や例外処理は全部省いて、概要だけ。
(10/30 コメントいただいて訂正しました)
var promise = Promise.resolve();
promise.then(function loop(count) {
setTimeout(function() {
crawling(hoge).then(function (res_s) {
return jump()
}).then(function (res_j) {
return wait()
}).then(function (res_w) {
return loop()
});
}, 2000);
count++;
}(count));
##内容
要は再帰関数です。
最初にresolve済みのPromiseを一つ生成してあげて、thenで再帰関数「loop」を定義してあげます。
再帰関数の中には、実行したい処理を順にthenで繋いであげて、最後にloopに戻れば、順番に実行した後頭に戻る(再帰的に実行する)処理となります。
色々と試行錯誤しましたが結局一番シンプルにうまく実装できたのがこの形式でした。
- 配列にPromiseを入れて、前のPromiseが終わるまで待ってみようとか
- async/awaitでなんかうまいことできないかなとか
方法はもっと色々あるのかもしれませんが、初心者にはPromise/thenが最もシンプルで理解しやすいのかなと。
#当たり前ですが
コード内のcrawlingやjump,wait等の関数は全てPromiseを返す関数です。
function crawling(hoge) {
return new Promise(function(resolve) {
/* クロール処理をかく */
resolve(response);
});
}
#おわりに
JavaScriptがとっても厄介な言語だということがわかりましたが、めげずに頑張っていこうと思います。
何かアドバイス等ございましたらコメントまでお願いします。
作成した拡張機能についても今後記事を書いていきたいです。