信号量,run_once装饰器或类似的东西

时间:2012-08-28 12:54:59

标签: javascript jquery

在某些地方,我们只需要运行一个函数实例。

此代码适用于我:

function example() { 
    var that = this; 
    if(that.running) { 
       return false; 
    }
    that.running = true; 
    $.get(url, {}, function (data) {
         that.running = false; 
    }); 
}

我们如何改进它,让它更可重复使用?

UPD 这是解决方案,基于Frits van Campen回答:

function make_run_once(callback) {
    callback.running = false;
    return function () {
        if(callback.running) {
            return false;
        }
        callback.running = true;
        deferred = $.Deferred();
        deferred.done(function () {
            callback.running = false;
        });
        callback(deferred);  // pass deferred to callback so it can resolve at it's own leisure
    };
}

2 个答案:

答案 0 :(得分:2)

您可能希望使用jQuery's `Deferred' functionality

function decorate(fn) {
    var deferred;
    return function(){
        if (!deferred) {
            deferred = new jQuery.Deferred;
            fn(deferred.resolve); // pass in the callback
        }
        return deferred;
    };
}

一个修饰函数将始终返回相同的Deferred对象,该对象将使用原始函数的回调来解析 - 在第一次调用时启动。

答案 1 :(得分:0)

这样的东西?

function make_run_once(callback) {
    var deferred = false;
    return function () {
        if (false === deferred) {
            return;
        } else {
            deferred = $.Deferred();
            deferred.done(function () {
                deferred = false;
            });
            callback(deferred);  // pass deferred to callback so it can resolve at it's own leisure
        }
    };
}

var once = make_run_once(function (deferred) {
    // do stuff, possible ajax stuff
    setTimeout(function () {
        deferred.resolve();  // resolve at some point so it become unblocked again
    }, 100);
});
once(); // run
once(); // block
once(); // block
once(); // block
setTimeout(once, 500);  // run

请求'替换'其他请求,你有吗?就像一个自动完成功能。您需要对其进行修改才能使其正常工作。您应该保留最新的请求,并在最后一个请求完成时触发它,而不是忽略新的请求。