Javascript - 异步调用后同步

2024-03-09

我有一个 Javascript 对象,需要 2 次调用外部服务器来构建其内容并执行任何有意义的操作。该对象的构建使得实例化它的实例将自动进行这两个调用。这两个调用共享一个公共回调函数,该函数对返回的数据进行操作,然后调用另一个方法。问题是在两个方法都返回之前不应调用下一个方法。这是我目前实现的代码:

foo.bar.Object = function() {
this.currentCallbacks = 0;
this.expectedCallbacks = 2;

this.function1 = function() {
    // do stuff
    var me = this;
    foo.bar.sendRequest(new RequestObject, function(resp) {
        me.commonCallback(resp);
        });
};

this.function2 = function() {
    // do stuff
    var me = this;
    foo.bar.sendRequest(new RequestObject, function(resp) {
        me.commonCallback(resp);
        });
};

this.commonCallback = function(resp) {
    this.currentCallbacks++;
    // do stuff
    if (this.currentCallbacks == this.expectedCallbacks) {
        // call new method
    }
};

this.function1();
this.function2();
}

正如您所看到的,我在两个调用返回后强制对象继续,使用一个简单的计数器来验证它们都返回了。这可行,但似乎是一个非常糟糕的实现。我现在只使用了 Javascript 几个星期,我想知道是否有更好的方法来完成我尚未偶然发现的同样的事情。

感谢您的任何和所有帮助。


除非您愿意序列化 AJAX,否则我无法想到其他方法来完成您所建议的操作。话虽这么说,我认为您所拥有的相当不错,但您可能需要稍微清理一下结构,以免用初始化数据创建的对象乱七八糟。

这是一个可能对您有帮助的函数:

function gate(fn, number_of_calls_before_opening) {
    return function() {
        arguments.callee._call_count = (arguments.callee._call_count || 0) + 1;
        if (arguments.callee._call_count >= number_of_calls_before_opening)
            fn.apply(null, arguments);
    };
}

该函数就是所谓的高阶函数,即以函数作为参数的函数。这个特定的函数返回一个函数,该函数在被调用时调用传递的函数number_of_calls_before_opening次。例如:

var f = gate(function(arg) { alert(arg); }, 2);
f('hello');
f('world'); // An alert will popup for this call.

您可以使用它作为回调方法:

foo.bar = function() {
    var callback = gate(this.method, 2);
    sendAjax(new Request(), callback);
    sendAjax(new Request(), callback);
}

第二个回调,无论它是什么,都会确保method叫做。但这会导致另一个问题:gate函数在没有任何上下文的情况下调用传递的函数,意思是this将引用全局对象,而不是您正在构造的对象。有几种方法可以解决这个问题:您可以关闭this通过将其别名为me or self。或者你可以创建another高阶函数就可以做到这一点。

第一种情况如下所示:

foo.bar = function() {
    var me = this;        
    var callback = gate(function(a,b,c) { me.method(a,b,c); }, 2);

    sendAjax(new Request(), callback);
    sendAjax(new Request(), callback);
}

在后一种情况下,另一个高阶函数将如下所示:

function bind_context(context, fn) {
    return function() {
        return fn.apply(context, arguments);
    };
}

该函数返回一个在传递的上下文中调用传递的函数的函数。其示例如下:

var obj = {};
var func = function(name) { this.name = name; };
var method = bind_context(obj, func);
method('Your Name!');
alert(obj.name); // Your Name!

从长远来看,您的代码将如下所示:

foo.bar = function() {
    var callback = gate(bind_context(this, this.method), 2);

    sendAjax(new Request(), callback);
    sendAjax(new Request(), callback);
}

无论如何,一旦进行了这些重构,您就已经清除了正在构造的对象,其中包含仅初始化所需的所有成员。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Javascript - 异步调用后同步 的相关文章

随机推荐