Ada beberapa pola desain yang dapat Anda gunakan di node.js untuk menjalankan operasi asinkron berurutan. Dalam semuanya, Anda tidak dapat menjalankan loop ketat menunggu sesuatu terjadi - Anda harus membiarkan utas Javascript tunggal di node.js berjalan dan memberikannya sebanyak mungkin siklus.
Iterasi Manual
Letakkan kode untuk iterasi dalam fungsi lokal (saya biasanya menyebutnya next()
) dan kemudian ketika satu iterasi memanggil fungsi penyelesaian terakhirnya, Anda dapat memanggil next()
lagi untuk memulai iterasi berikutnya. Anda dapat menyelesaikan operasi dengan menguji beberapa kondisi dan tidak memanggil next()
jika semuanya sudah selesai atau baris pertama next()
dapat menguji untuk melihat apakah Anda sudah selesai.
Lihat contoh kode di bawah ini untuk mengetahui bagaimana kode Anda akan terlihat dengan iterasi manual.
Janji urutan
Jika Anda menggunakan janji untuk operasi asinkron, Anda dapat membiarkan janji yang dirantai melakukan semua pengurutan untuk Anda seperti dalam p().then(f1).then(f2).then(f3)
. Anda dapat melihat contohnya dalam jawaban ini:Janji seperti async.each
.
Gunakan Modul Asinkron
Modul asinkron mendukung sejumlah fungsi manajemen async. Banyak yang menganggapnya sangat berguna - yang lain lebih suka menggunakan janji untuk menyelesaikan masalah serupa. Bagaimanapun, ia memiliki sejumlah fungsi berbeda untuk pengurutan. Misalnya jika Anda ingin mengulangi array secara asinkron, Anda akan menggunakan sesuatu seperti ini:
async.eachSeries(hugeArray, function iterator(item, callback) {
if (inCache(item)) {
callback(null, cache[item]); // if many items are cached, you'll overflow
} else {
doSomeIO(item, callback);
}
}, function done() {
//...
});
Berikut adalah versi kode Anda yang melakukan iterasi manual menggunakan next()
custom khusus fungsi iterasi.
function runQuery(callback) {
mysql.getConnection(function(err, connection) {
if (err) {
connection.release();
callback(err);
return;
}
var array = [];
var count = 10;
var index = 0;
function next() {
if (index++ < count) {
array.push([index, 'master']);
console.log('100-elements');
connection.beginTransaction(function(err) {
if (err) {
// can't throw here in an async function
// use callback to communicate error
callback(err);
return;
}
var query = "insert into users(username, password) values ?";
connection.query(query, [array], function(err, rows) {
if (!err) {
//commit start
connection.commit(function() {
if (err) {
console.error(err);
connection.rollback(function() {
console.error('rollback error');
callback(err);
return;
});
} else {
console.log("Commit");
// now do the next iteration
next();
} // if err
}); //commit end
} else {
console.log(err);
connection.rollback(function() {
callback(err);
return;
});
} // if
});
});
}
}
});
}