我有一个函数可以像保存到数据库一样执行异步操作。想要一个首先插入行的机制,并且只有在第一个插入操作完成时才会发生下一次插入。
这是我尝试过的,它有点奏效。
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中定时器的理解。
答案 0 :(得分:3)
不,你不应该在完成任务时创建计时器来进行轮询。这可能是你能做到的最糟糕的方式。你想要做的是每次上一次迭代结束时显式开始下一次迭代。
这是关于如何在没有轮询的情况下执行此操作的一般概念。我们的想法是你需要创建一个可以连续调用的函数,每次调用它时,它都会执行下一次迭代。然后,您可以从异步操作的完成处理程序中调用该函数。由于您没有一个方便的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();
}
如果您没有数据,这种数据很容易以这种方式逐步执行,那么您可以在需要时获取数据的每次下一次迭代(在没有更多数据时停止)或在开始操作并使用收集的数组之前,您可以将所有数据收集到一个数组中。
答案 1 :(得分:1)
不,这绝对不是正确的方法。让我们假设row
包含10个值,然后您创建10个独立的计时器,这些计时器连续运行并检查它们是否可以插入。而且它甚至不能保证它们按照它们的创建顺序执行。
正如jfriend00已经提到的,你应该省略“循环”并使用保存操作的完成回调。像这样:
var rows = [...];
function insert(rows, index) {
index = index || 0;
var current_element = rows[index];
model.save(function() {
if (index < rows.length - 1) {
insert(rows, index + 1);
}
});
}
insert(rows);
注意在保存操作完成后函数如何调用自身(以某种方式),增加索引,以便数组中的下一个元素被“保存”。
答案 2 :(得分:0)
我会使用一个处理异步内容的库,例如async.js
BTW看起来你的model.save方法需要一个回调,你可以直接使用它来调用insert方法。如果插入函数是你自己创建的,而不是某个更大框架的一部分,我建议重新编写它并将回调作为参数,并使用它而不是使用setInterval来检查异步工作完了。