javascript - Promise.all() 的行为出乎意料,我哪里缺乏理解?

标签 javascript node.js loops promise

我正在尝试编写一个使用 GitHub API 的脚本。我有一个接受用户名列表的函数。对于每个用户名,都会调用 API 以获得该用户加星标的存储库。对于每个用户加星标的存储库,我想捕获存储库的名称和星数,最终我想利用这些数据做更多的工作。

我正在尝试仅使用 native promise 来实现此功能,并避免使用 Q、Bluebird 等。这是我所拥有的不起作用的内容。

function getNameAndStarInfo(repo){
  return new Promise(function(resolve, reject){
    //i'd like this to return an object but it has to be an iterable??
    resolve([{[repo.full_name] : repo.stargazers_count}]); 
  });
};

function getStarredRepos(usernames){
  var promises =[];
  for (var user in usernames){
    //build the header for API request

    var name = usernames[user];
    var url = 'https://api.github.com/users/' + name + '/starred';
    var header = {url: url, headers: {'User-Agent': 'username', 'Authorization': 'token blahblabhlabh'}, json: true };

    //for the current user make a request and get their starred repos
    request(header, function(err, res, usersStarredRepos){
        for (var repo in usersStarredRepos){
            promises.push(getNameAndStarInfo(usersStarredRepos[repo]));

        };
    });
   };
   Promise.all(promises)
      .then(function(promises){
        //dont need to log, would like to do stuff with this data later
        console.log(promises);
    });

};

本质上,当我在 .then() 方法中记录数组时,我希望看到所有的 {name: stargazers_count} 数据。但是每次都会输出一个空数组。有人可以向我解释一下我在这里缺少什么吗?

最佳答案

仅当请求已完成时,您才推送 promise 。因此,当执行 Promise.all 时,数组仍然为空,因为它们都还没有完成。

尝试用这种方式:

function getNameAndStarInfo(repo) {
    return new Promise(function(resolve, reject) {
        //i'd like this to return an object but it has to be an iterable??
        resolve([{
            [repo.full_name]: repo.stargazers_count
        }]);
    });
}

function getUserStars(username) {
    return new Promise(function(resolve, reject) {
        var name = username.name;
        var url = 'https://api.github.com/users/' + name + '/starred';
        var header = { url: url, headers: { 'User-Agent': 'username', 'Authorization': 'token blahblabhlabh' }, json: true };
        //for the current user make a request and get their starred repos
        request(header, function(err, res, usersStarredRepos) {
            var promises = [];
            for (var repo in usersStarredRepos) {
                promises.push(getNameAndStarInfo(usersStarredRepos[repo]));
            };
            Promise.all(promises).then(resolve).catch(reject);
        });
    });
}

function getStarredRepos(usernames) {
    var promises = [];
    for (var user in usernames) {
        promises.push(getUserStars(usernames[user]));
    }
    Promise.all(promises).then(console.log).catch(console.log);
}

但是为了避免手动创建Promises来处理请求,我建议您使用request-promise:

https://www.npmjs.com/package/request-promise

关于javascript - Promise.all() 的行为出乎意料,我哪里缺乏理解?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39518918/

相关文章:

javascript - 如何在 forEach 循环运行时阻止它不被执行两次?

javascript - 如何分别测试 ExpressJS 路由和 'controller'

javascript - 在函数 CoffeeScript 中获取对象值

javascript - Socket.io:如何让每个人获得不同的 channel ?

javascript - 在 SIRV S3 NodeJ 中的文件夹之间移动图像

java - try catch Trouble//while 循环放置

algorithm - 带循环的拓扑排序

C++ 程序不从文件中读取字符

magento静态 block 中的javascript幻灯片

javascript - Visual Studio XML 架构注释(与 :htmlequivalent) 相比