Javascript 检查回调是否上次触发的方法?

Javascript 检查回调是否上次触发的方法?,javascript,Javascript,我目前有一个函数,看起来像: 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: // d

我目前有一个函数,看起来像:

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()
比第二次调用完成得早。从客户的角度来看,它是这样的:

var update = outdated(buildUpdate, function(result) {
    // send update to clients
});

update();
// do some changes
update();
  • 接收根据数据状态1计算的更新
  • 接收根据数据状态3计算的更新
  • 接收根据数据状态2计算的更新(不应发送此更新)
是否有任何设计模式或功能有助于避免此类情况

注意:如果客户端没有收到所有更新,这并不重要。重要的是,最后一次接收的数据必须与当前数据状态一致


我的想法是在每次调用
update()
时生成一个随机ID。之后,我检查回调的ID是否与上次生成的ID匹配。然而,ID的生成本身引入了一个新的异步计算,并在每次使用中产生更多的代码。

最简单的方法可能是添加回调

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....
         });
     });
 });

如果添加中间件,您将有更高级的方法来处理异步行为。

最简单的方法可能是添加回调

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....
         });
     });
 });

如果添加中间件,您将有更高级的方法来处理异步行为。

最简单的方法可能是添加回调

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....
         });
     });
 });

如果添加中间件,您将有更高级的方法来处理异步行为。

最简单的方法可能是添加回调

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....
         });
     });
 });

如果添加中间件,您将有更先进的方法来处理异步行为。

我目前的方法可行,但可能不是最好的解决方案。 如果您知道更好的方法,请提交答案。

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();

我目前的方法可行,但可能不是最好的解决方案。 如果您知道更好的方法,请提交答案。

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();

我目前的方法可行,但可能不是最好的解决方案。 如果您知道更好的方法,请提交答案。

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();

我目前的方法可行,但可能不是最好的解决方案。 如果您知道更好的方法,请提交答案。

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();


A:不管你的平台是node.js,这个问题与node.js无关B:当第二次调用更新时,你希望发生什么?如果答案是B,我想我可以用一个比你的随机答案更好的主意来帮助你ID@GeorgeJempty你说得对,我为错误的标签道歉。B:看修改后的问题。A:不管你的平台是node.js,这个问题与node.js无关B:当第二次调用更新时,你希望发生什么?如果答案是B,我想我可以用一个比你的随机答案更好的主意来帮助你ID@GeorgeJempty你说得对,我为错误的标签道歉。B:看修改后的问题。A:不管你的平台是node.js,这个问题与node.js无关B:当第二次调用更新时,你希望发生什么?如果答案是B,我想我可以用一个比你的随机答案更好的主意来帮助你ID@GeorgeJempty你说得对,我为错误的标签道歉。B:看修改后的问题。A:不管你的平台是node.js,这个问题与node.js无关B:当第二次调用更新时,你希望发生什么?如果答案是B,我想我可以用一个比你的随机答案更好的主意来帮助你ID@GeorgeJempty你说得对,我为错误的标签道歉。B:看修改后的问题,谢谢你的建议。是否有一种方法可以应用于两个以上的更新调用?(如修订后的示例中所示)@ted-尽可能多地应用它(请参见更新的答案),但如果您要多次使用它,有更好的方法,例如,我想到了递归,但这比嵌套函数稍微复杂一点。您应该考虑使用jQuery保证对象来处理异步问题。谢谢您的建议。是否有一种方法可以应用于两个以上的更新调用?(如修订后的示例中所示)@ted-尽可能多地应用它(请参见更新的答案),但如果您要多次使用它,有更好的方法,例如,我想到了递归,但这比嵌套函数稍微复杂一点。您应该考虑使用jQuery保证对象来处理异步问题。谢谢您的建议。我