Javascript 回调不起作用,在 ajax 请求完成之前运行回调

标签 javascript jquery

我正在尝试理解回调。我有这段代码,可以从控制台运行。我想从数组用户那里获取 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/

相关文章:

javascript - 如何修复浏览器移动 View 中未定义问题的 jQuery 'length'?

php - 移动到另一页时发出警报

javascript - 在 Node JS 中下载文件

javascript - jQuery 在单击时更改甚至在加载事件时更改

javascript - 使用运行 php 代码的 ajax 更改按钮

javascript - 鼠标悬停时保持工具提示(标题属性)更新

javascript - 如何获取json对象的部分值

javascript - 在固定大小的 block 内显示带有圆 Angular 的任意大小的图像

javascript - 在复选框中显示来自 mySQL 的 true 或 false (0/1)

javascript - fotorama:无法获取 API 对象(未定义)