LoginSignup
1
1

More than 5 years have passed since last update.

非同期処理を含むループをシリアルに処理したい場合に AsyncAwait でスッキリ書くスニペット

Posted at

はじめに

ついこの前、Node.js の LTS が 6系になったと思ったら、次の LTS(8系) のリリースまで 残り 1ヶ月くらいになってしまいました。
待ちに待った AsyncAwait の登場ですね!

本文

今までさんざん面倒だった、非同期処理のシリアルループが、AsyncAwaitでスッキリするよという例です。

MongoDB で、一つのコレクションの内容を、もう一方にコピーする場合を例にします。
(関係ないフィールドは値を保持)

Node.js 8.2、MongoDB は 3.4、ドライバは2.2を使っています。

const mongodb = require('mongodb');

const uri = process.env.MONGO_URI || 'mongodb://127.0.0.1:27017/test?max_pool_size=1';

// コレクションのコピー
const copy = async (db, from, to) => {
  const src = db.collection(from);
  const dst = db.collection(to);

  const cond = {}; // 検索条件

  const cursor = src.find(cond);

  const update = (c) => {
    return c.next().then(obj => {
      const { _id } = obj;
      return dst.updateOne({ _id }, { $set: obj }, { upsert: true });
    });
  };

  while (await cursor.hasNext()) {
    await update(cursor);
  }
};

// メイン
let db;
mongodb.MongoClient.connect(uri).then(_db => {

  db = _db;
  return copy(db, 'data_src', 'data_dst');

}).then(() => {
  db && db.close();
  process.exit(0);
}).catch(e => {
  db && db.close();
  process.exit(-1);
});

まとめ

結局、重要なことは

  • 「async 関数」は、実行することで promise になる
  • await は async 関数内部だけで有効なキーワード
  • promise に await を付ければ、そこで非同期処理の終了を待ってくれる
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1