我正在尝试理解回调。我有这段代码,可以从控制台运行。我想从数组用户那里获取 github 配置文件,当它们全部加载(显示在控制台上)时,我想在控制台上显示“完成”。我正在使用回调,我认为这就是我的问题所在。
不幸的是,控制台上显示“已完成”,然后是来自 github 的数据。显然它是异步的,并且回调不起作用。我能做什么?
这是输出
VM134355:24 Finished
undefined
VM134355:4 Object {login: "Amichai", id: 313874, avatar_url: "https://avatars.githubusercontent.com/u/313874?v=3", gravatar_id: "", url: "https://api.github.com/users/Amichai"…}
VM134355:5 Amichai has 65 public repositories!
VM134355:4 Object {login: "adamwiggins", id: 177, avatar_url: "https://avatars.githubusercontent.com/u/177?v=3", gravatar_id: "", url: "https://api.github.com/users/adamwiggins"…}
VM134355:5 Adam Wiggins has 94 public repositories!
VM134355:4 Object {login: "fzzr-", id: 888526, avatar_url: "https://avatars.githubusercontent.com/u/888526?v=3", gravatar_id: "", url: "https://api.github.com/users/fzzr-"…}
VM134355:5 Alexander "FIZZΞR" Koz. has 129 public repositories!
代码是
function makeRequest(url,index,array){
function printRepoCount() {
var responseObj = JSON.parse(this.responseText);
console.log(responseObj);
console.log(responseObj.name + " has " + responseObj.public_repos + " public repositories!");
}
var request = new XMLHttpRequest();
request.onload = printRepoCount;
request.open('get', url, true);
request.send();
}
function loadPages(files, _callback) {
files.forEach(makeRequest);
_callback();
}
var users = ['https://api.github.com/users/Amichai',
'https://api.github.com/users/adamwiggins',
'https://api.github.com/users/fzzr-'];
(function runFunction(){
loadPages(users, function() {
console.log('Finished');
});
})();
最佳答案
您可能想查看Promises ,但如果您想坚持使用您的代码,您可以使用计数器包装 makeRequest() 方法,如下所示:
function makeRequest(url,index,array){
function printRepoCount() {
var responseObj = JSON.parse(this.responseText);
console.log(responseObj);
console.log(responseObj.name + " has " + responseObj.public_repos + " public repositories!");
}
var request = new XMLHttpRequest();
request.onload = printRepoCount;
request.open('get', url, true);
request.send();
// Don't forget to return the request!
return request;
}
function loadPages(files, _callback) {
var files_count = files.length,
files_loaded = 0;
files.forEach(function(file) {
var request = makeRequest(file);
var req_onload = request.onload;
request.onload = function(t) {
req_onload.bind(this)(t);
files_loaded++;
if (files_loaded === files_count) {
_callback();
}
}
});
}
我更改了 loadPages
来更改从 makeRequest
返回的请求对象的 onload
方法 - 首先我将原始 onload 保存在 中req_onload
然后我将其替换为一个触发原始方法(在事件本身的上下文中)的方法,然后递增计数器 (files_loaded
)。当 files_loaded
达到 files_count
时,它会触发您的 _callback
方法。
可以在这个fiddle查看
关于Javascript 回调不起作用,在 ajax 请求完成之前运行回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38282481/