2

假设您想在 JavaScript 中发出一个异步请求,但您想将一些状态传递给回调方法。以下是 JavaScript 中对闭包的适当使用吗?

function getSomethingAsync(someState, callback) {
    var req = abc.createRequestObject(someParams);
    req.invoke(makeCallback(someState, callback));
}

function makeCallback(someState, callback) {
    return function getSomethingCallback(data) {
        var result = processDataUsingState(data, someState);
        callback(result); // alternately/optionally pass someState along to result
    }
}

如果没有,是否有更好或更惯用的方法?

4

4 回答 4

2

我没有看到任何直接的问题 - 闭包之所以强大有很多原因,其中之一是消除了使用全局变量进行状态维护的需要。

也就是说,关于闭包,您唯一需要警惕的是通常发生在 IE 中的内存泄漏,但这些通常是 IIRC,与 DOM 元素和附加的事件处理程序相关。

继续!

于 2008-10-30T19:08:58.490 回答
1

更惯用的方法是使用Function.bind,然后您不需要复制代码来创建闭包。我将使用一个简单的示例(没有您的自定义代码)来解释

/**
 * Retrieves the content of a url asyunchronously
 * The callback will be called with one parameter: the html retrieved
 */
function getUrl(url, callback) {
    $.ajax({url: url, success: function(data) {
        callback(data);
    }})    
}

// Now lets' call getUrl twice, specifying the same 
// callback but a different id will be passed to each
function updateHtml(id, html) {
    $('#' + id).html(html);
}


// By calling bind on the callback, updateHTML will be called with 
// the parameters you passed to it, plus the parameters that are used
// when the callback is actually called (inside )
// The first parameter is the context (this) to use, since we don't care,
// I'm passing in window since it's the default context
getUrl('/get/something.html', updateHTML.bind(window, 'node1'));
// results in updateHTML('node1', 'response HTML here') being called
getUrl('/get/something-else.html', updateHTML.bind(window, 'node2'));
// results in updateHTML('node2', 'response HTML here') being called

Function.bind是新的,所以如果您需要向后支持,请查看兼容性部分 Function.bind

最后,我知道这个问题没有被标记为 jQuery。这只是在不处理跨浏览器问题的情况下显示异步函数的最快方法

于 2012-01-19T17:31:58.197 回答
0

使用匿名函数更好(更好):

function getSomethingAsync (someState, callback) {
    req.invoke (function (data) {
       var result = processDataUsingState (data, someState);
       callback (result);
    });
}
于 2008-10-30T19:05:51.367 回答
0

您还可以使用 call() / apply() 在函数中操作“this”的值。

例如,指定异步方法的另一个参数是在回调中用作“this”的对象。这就是 jQuery 在事件回调中将 dom 节点设置为“this”的方式。

function getSomethingAsync(callback, scope) {
    var req = abc.createRequestObject(someParams);
    req.invoke(function(rsp) {
      callback.apply(scope, [rsp]);
    });
}

// usage:
getSomethingAsync(function() {console.log(this.someState)}, {someState:'value'});
于 2012-01-22T21:57:52.760 回答