はじめに
ついこの前、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 を付ければ、そこで非同期処理の終了を待ってくれる