【问题标题】:Get data from API and continue when done从 API 获取数据并在完成后继续
【发布时间】:2017-07-21 20:33:09
【问题描述】:

我在 nodejs 中循环获取 api 请求时遇到问题。我想从多个端点获取数据并在所有请求完成后继续。我尝试了类似的方法,但它正在运行异步并记录一个空数组。任何提示如何确定所有请求何时准备就绪?

var api_endpoints = { "1": "url1", "2": "url2", "3": "url3" };

var allApiSources = [];
_.each(api_endpoints, function (val, key) {
    request(val, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var data = JSON.parse(body);
            _.each(data.url, function (val, key) {
                allApiSources.push(value);
            });
        }
    });
});
console.log(allApiSources); // []

谢谢!

【问题讨论】:

  • 1.使用 promises 或 2. 使用 asyncjs 或 3. 使用计数器来计算已推送到数组的值的数量,当它们全部完成后,您将拥有所有数据(不过,我不会推送到如果顺序很重要,则为数组 - 因为异步代码是异步的)
  • 顺序在这里并不重要:)
  • 我不能真正使用计数器,因为值的数量是动态的并且经常变化。
  • 你正在使用_.each ...所以...为什么计数器不合适?
  • 好吧,因此你可以使用 api_endpoints.length 因为你不知道确切的长度

标签: javascript node.js asynchronous request underscore.js


【解决方案1】:

使用promisesObject.values

一个假设...... data.url 是一个对象,而不是一个数组

另一个假设是,在您的原始代码中 allApiSources.push(value); 应该是 allApiSources.push(val);

var api_endpoints = { "1": "url1", "2": "url2", "3": "url3" };

Promise.all(Object.values(api_endpoints).map(value => new Promise((resolve, reject) => {
    request(value, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var data = JSON.parse(body);
            // you can remove the Object.values call if data.url is an Array
            return Object.values(data.url);
        }
        reject(error || response.statusCode);
    });
})))
.then(results => [].concat(...results)) // flattens the array of arrays
.then(allApiSources => {
    console.log(allApiSources);
});

【讨论】:

  • 谢谢,这看起来很有希望:)
  • 啊,我知道你在那里做了什么:p
【解决方案2】:

您需要使用 async npm,因为调用是异步的,您将无法打印值,async 模块允许您运行多个异步调用,然后将结果映射到单个数组

http://caolan.github.io/async/

async.map(['url1','url2','url3'], request, function(err, allApiSources) {
      console.log(allApiSources); // []

    // allApiSources is now an array of responses for each request
});

【讨论】:

  • 哇...异步处理 response.statusCode,解析正文并为您提取值!这有多聪明!!!
  • 呵呵..也有没有办法从数组/对象中获取地图值,还是我必须在那里手动写入所有 url?
  • async.map 将根据文档接受一个 OBJECT - 这个答案中遗漏了很多细节来解释它如何为您工作!
  • Object.values({ "1": "url1", "2": "url2", "3": "url3" }) => ['url1','url2','url3']
猜你喜欢
  • 1970-01-01
  • 2022-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多