我有一个功能,它可以执行一些异步操作,例如保存到数据库。想要一种首先插入该行并且仅在第一个插入操作完成后才进行下一次插入的机制。
这是我尝试过的方法,有些起作用。
var interval = true;
function insert() {
model.save(function () {
interval = true;
})
}
foreach(row, function (key, val) {
var interval1 = setInterval(function () {
if (interval) {
insert();
interval = false;
clearInterval(interval1);
}
}, 100)
})
这是正确的方法吗?请阐明我对javascript中的计时器的理解。
最佳答案
不,您不应该创建用于轮询完成时间的计时器。那可能是最糟糕的方法。您要做的是在每次上一个迭代结束时显式启动下一个迭代。
这是您无需轮询即可执行此操作的一般思路。这个想法是,您需要创建一个可以连续调用的函数,每次调用该函数,它将执行下一次迭代。然后,您可以从异步操作的完成处理程序中调用该函数。由于没有一个方便的foreach循环来控制迭代,因此必须找出需要跟踪哪些状态变量以指导每次迭代。如果您的数据是一个数组,那么您所需要的只是该数组的索引。
function insertAll(rows) {
// I'm assuming rows is an array of row items
// index to keep track of where we are in the iteration
var rowIndex = 0;
function insert() {
// keep going as long as we have more rows to process
if (rowIndex < rows.length) {
// get rows[rowIndex] data and do whatever you need to do with it
// increment our rowIndex counter for the next iteration
++rowIndex;
// save and when done, call the next insert
model.save(insert)
}
}
// start the first iteration
insert();
}
如果您的数据没有以这种方式一次很容易地遍历一个数组,那么您可以在需要时获取数据的每个下一次迭代(在没有更多数据时停止),或者可以收集在开始操作并使用收集的数组之前,将所有数据放入一个数组中。