Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8691

firebase データ取得にfor文を使いつつ、その中で非同期処理する方法

$
0
0

この記事は、どっかからAPIをとってきたデータを、firebaseのデータ群と比較参照する場合、
非同期処理とfor文をどうやって組み合わせれば良いかというところにいつも引っかかっていてしまっていたので、その備忘録です。

環境

  • Node.js
  • Cloud firestore

どんな問題なのか

firestore にあるcollection からデータを全てとってくる場合、下記の例のように、forEachを使ってとってくるのが普通です。

varquery=db.collection('contents').get();query.then(function(snapshot){snapshot.forEach(function(childSnapshot){...// childsnapshot の処理});});

しかし、このforEach文の中、つまり、childsnapshotの処理の中に、時間がかかる関数を呼び出していて非同期処理をする必要があるとなった場合、
forEachは非同期処理に対応していないため、一筋縄でいかないのが問題でした。

具体的に、下記のような重い処理をchildSnapshotの処理内で行うと、

varquery=db.collection('contents').get();query.then(function(snapshot){snapshot.forEach(asyncfunction(childSnapshot){console.log('before_func');awaitheavyfunc(childSnapshot);//重い処理console.log('after_func');});});constheavyfunc=function(data){...// API をとってくるなどの重い処理console.log('inside_func');}
// snapshot が2つのdataを持っている場合before_funcafter_funcbefore_funcafter_funcinside_funcinside_func

このような結果が得られ、heavyfuncの処理がforEachの処理に追いついていない状態になります。

どうやったか

varquery=db.collection('contents').get();query.then(asyncfunction(snapshot){forawait(letchildSnapshotofsnpashot.docs){console.log('before_func');awaitheavyfunc(childSnapshot);//重い処理console.log('after_func');}});constheavyfunc=function(data){...// API をとってくるなどの重い処理console.log('inside_func');}

forEachではなく、for ~ ofを使ってループ内での非同期処理を実現しました。

具体的に

  • for ~ ofを使う際、そのループにもawaitを付けたす必要がありました。
  • snapshotのデータを一つずつ取ってくる時に、snapshot.docsのようにdocsを呼び出さないと、データを取得することが出来ませんでした。

Viewing all articles
Browse latest Browse all 8691

Trending Articles