通过回调将数据传回匿名函数?
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();
}
一些没有提供解决方案的相关帖子:
- This one 与我想做的相反。
- This one 不传递参数。
有没有办法将变量传递给匿名回调函数而不是创建命名函数?
在您原来的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}`);
});
最近我一直在研究 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();
}
一些没有提供解决方案的相关帖子:
- This one 与我想做的相反。
- This one 不传递参数。
有没有办法将变量传递给匿名回调函数而不是创建命名函数?
在您原来的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}`);
});