通过回调将数据传回匿名函数?

Pass data back to anonymous function via callback?

最近我一直在研究 JavaScript 语言的回调函数,在测试期间我遇到了一个我没有预见到的问题,但是一旦遇到它,我就明白了问题是什么很有可能。

为了学习目的,我编写了两种协同工作调用 Stack Exchange API 的方法。第一个构建请求 URL,第二个调用 Web 服务本身。

function getSEWebServiceResponse(request, callback) {
    var apiRoot = 'https://api.stackexchange.com/2.2/';
    var key = 'key=s29XM)Eqn2x3YxhjLgFwBQ((';
    if (request.indexOf('?') >= 0)
        key = '&' + key;
    else
        key = '?' + key;

    getWebServiceResponse(apiRoot + request + key, callback);
}
function getWebServiceResponse(requestUrl, callback) {
    var request = new XMLHttpRequest();
    request.open('GET', requestUrl, true);
    request.onload = function() {
        if (request.status < 200 || request.status >= 400)
            callback("An unexpected error occurred.");
        else
            callback(JSON.parse(this.response));
    };
    request.send();
}

现在,这个实现很简单,但我 运行 遇到的问题是传回响应导致 undefined,我相信原因是我使用了一个匿名函数作为getSEWebServiceResponse:

的回调
function getAssociatedAccounts(accountID, callback) {
    var url = 'users/' + accountID + '/associated';
    getSEWebServiceResponse(url, function() {
        if (!this.items) // this.items is undefined.
            return;

        var accounts = sortAccountsByReputation(this.items);
        //... DO MORE STUFF
        callback();
    });
}

我认为简单的解决方案是创建一个已定义的函数(但我觉得应该有一种方法可以使用匿名函数来实现):

function getAssociatedAccounts(accountID, callback) {
    var url = 'users/' + accountID + '/associated';
    getSEWebServiceResponse(url, processAssociatedAccounts);
}
function processAssociatedAccounts(response) {
    if (response.items)
        return;

    var accounts = sortAccountsByReputation(this.items);
    //... DO MORE STUFF
    callback();
}

一些没有提供解决方案的相关帖子:


有没有办法将变量传递给匿名回调函数而不是创建命名函数?

在您原来的getAssociatedAccounts中使用匿名回调,您不接受响应参数。将其更改为以下应该有效

function getAssociatedAccounts(accountID, callback) {
    var url = 'users/' + accountID + '/associated';
    getSEWebServiceResponse(url, function(response) { // accepted response as parameter
        if (!response.items) // this.items is now response.items.
            return;

        var accounts = sortAccountsByReputation(response.items);
        //... DO MORE STUFF
        callback();
    });
}

函数是命名的还是匿名的并不重要。重要的是:

  • 调用时传递参数
  • 它对这些参数做了一些处理

例如:

let counter = 1;

function i_take_a_callback(callback) {
  callback(counter++);
}

function i_have_a_name(value) {
  console.log(`I have a name and am logging ${value}`);
}

i_take_a_callback(i_have_a_name);

i_take_a_callback(function(value) {
  console.log(`I am anonymous and am logging ${value}`);
});