我目前有一个看起来像这样的功能:
function update() {
buildUpdate(function(result) {
// send result to clients
});
}
这通常可以正常工作。但是,如果我这样做:
// data state 1
update(); // this time, buildUpdate() won't take a long time
// do some work resulting in:
// data state 2
update(); // this time, buildUpdate() will take a long time
// and thus will finish after the third call
// do some work resulting in:
// data state 3
update(); // this time, buildUpdate() won't take a long time
正如预期的那样,客户将收到三个更新。但是它们的顺序错误,因为update()
的第三次调用确实早于第二次调用。从客户的角度来看,它看起来像这样:
是否有任何设计模式或功能有助于避免这种情况?
注意:如果客户端未收到所有更新,则无关紧要。重要的只是收到的最后一个必须与当前数据状态一致。
我的想法是在update()
每次调用时生成一个随机ID。然后我检查回调它的ID是否与生成的最后一个ID匹配。然而,ID本身的生成引入了新的异步计算,并在每次使用时产生了更多的代码。
答案 0 :(得分:3)
最简单的可能是添加回调
function update(callback) {
buildUpdate(function(result) {
// send result to clients
if (typeof callback == 'function') callback();
});
}
并做
update(function() { // when the first one finishes
update(function() { // run the second one
update(function() { // and when the second is finished, the third
update(); // and so on....
});
});
});
如果添加async中间件,则可以使用更高级的方法来处理异步行为。
答案 1 :(得分:0)
我目前的方法有效,但可能不是最好的解决方案。 如果您有更好的方法,请提交答案。
var outdated = function(f, cb) {
var counter = 0;
var finished = -1;
return function() {
var no = counter++;
a = [].slice.call(arguments);
a.unshift(function() {
if(no > finished) {
finished = no;
cb.apply(this, arguments);
}
});
f.apply(this, a);
};
};
让我们考虑以下示例:
var example = outdated(function(cb, a) {
setTimeout(function() {
cb(a);
}, a * 1000);
}, function(c) {
console.log('finished '+c);
});
example(1);
example(4);
example(2);
这将产生以下输出:
finished 1
finished 2
finished 4
未在finished 2
之前调用,但在之后结束。
要解决问题中所述的实际问题,我会调用这样的函数:
var update = outdated(buildUpdate, function(result) {
// send update to clients
});
update();
// do some changes
update();