【问题标题】:How to make synchronous forEach loop and make an Asynchronous request to an API in Javascript如何在 Javascript 中进行同步 forEach 循环并向 API 发出异步请求
【发布时间】:2019-02-24 02:20:44
【问题描述】:

我正在尝试使用参数数组创建 API,然后使用该值进行另一个 API 调用以获取另一个数组。使用 javascript,但我每次都背着沙子。

var axios = require('axios');
var otp= [
  'bitcoin', 'cat', 'orange', 'mango', 'bats', 'california'
];
optDetails = [];
const promises = otp.map(info => axios.get(`https://www.iot.com/api/?query=${info}`).then(res => res.data));

const newPromise = Promise.all(promises).then(stateData => {
    optDetails.push(stateData)
    optDetails.map(nextData => axios.get(`https://www.crypto.com/api/?query=${nextData.uuid}`).then(res => res.data))
});

Promise.all(newPromise).then((res) => {
    console.log(res)
}, err => console.log(err));

但是我得到了这个错误

TypeError: undefined is not a function
    at Function.all (<anonymous>)
    at Object.<anonymous> (/home/runner/index.js:13:9)
    at Module._compile (internal/modules/cjs/loader.js:654:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:695:10)
    at startup (internal/bootstrap/node.js:201:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:516:3)

【问题讨论】:

  • optDetails.push(stateData) 看起来不对 - 请注意 stateData 本身就是一个数组
  • 那么我如何将它附加到另一个arrsy或者我应该循环它
  • 鉴于optDetails 为空,只需丢弃它并使用stateData 而不是optDetails

标签: javascript node.js reactjs api


【解决方案1】:

在您的第二个.map() 上,您正在创建另一个承诺数组,您需要从.then() 处理程序中返回它并使用Promise.all()

optDetails.map() 的结果是一个 promise 数组。您需要在上面使用Promise.all(),然后返回新的承诺。改变这个:

const newPromise = Promise.all(promises).then(stateData => {
    optDetails.push(stateData)
    optDetails.map(nextData => axios.get(`https://www.crypto.com/api/?query=${nextData.uuid}`).then(res => res.data))
});

到这里:

const newPromise = Promise.all(promises).then(stateData => {
    optDetails.push(stateData)
    return Promise.all(optDetails.map(nextData => axios.get(`https://www.crypto.com/api/?query=${nextData.uuid}`).then(res => res.data)));
});

newPromise.then((res) => {
    console.log(res)
}, err => console.log(err));

或者完全去掉中间的newPromise变量:

Promise.all(promises).then(stateData => {
    optDetails.push(stateData)
    return Promise.all(optDetails.map(nextData => axios.get(`https://www.crypto.com/api/?query=${nextData.uuid}`).then(res => res.data)));
}).then((res) => {
    console.log(res)
}, err => console.log(err));

另外optDetails.push(stateData) 看起来不对。我不知道你的数据结构实际上是什么,但stateData 本身是一个数组(从前面的Promise.all() 解析。也许你的意思是optDetails = stateData?或者你想将stateData 连接到已经存在的内容上optDetails?


更简单的版本

在我看来,如果您将多个循环更改为一个循环,这会导致代码更简单。您仍然会得到相同的结果数组。

var axios = require('axios');
var otp = [
  'bitcoin', 'cat', 'orange', 'mango', 'bats', 'california'
];

Promise.all(otp.map(info => axios.get(`https://www.iot.com/api/?query=${info}`).then(res => {
    return axios.get(`https://www.crypto.com/api/?query=${res.data.uuid}`).then(res2 => res2.data);
}))).then(results => {
    console.log(results);
}).catch(err => {
    console.log(err);
});

【讨论】:

  • 正如我所说,所以 +1 :-)
  • @user3424387 - 你看到我的“更简单的版本”了吗?我认为这更容易理解,甚至可能会更快一些,因为它如何在不同主机之间交替请求。
【解决方案2】:

您的newPromiseundefinedthen 回调的返回值)的承诺(由Promise.all(…).then(…) 创建)。您需要在此处添加return

然后你在newPromise 上调用Promise.all - 但newPromise 不像一组承诺那样是可迭代的。也许您希望它是由optDetails.map() 创建的承诺数组的承诺,但即便如此:在从then 回调返回承诺之前,您必须立即在数组本身上调用Promise.all

你最有可能在寻找

var axios = require('axios');
var otp = ['bitcoin', 'cat', 'orange', 'mango', 'bats', 'california'];

const promises = otp.map(info => axios.get(`https://www.iot.com/api/?query=${info}`).then(res => res.data));
const newPromise = Promise.all(promises).then(stateData => 
    Promise.all(stateData.map(nextData => axios.get(`https://www.crypto.com/api/?query=${nextData.uuid}`).then(res => res.data)))
);

newPromise.then((res) => {
    console.log(res)
}, err => {
    console.log(err)
});

【讨论】:

    猜你喜欢
    • 2020-02-18
    • 2017-03-17
    • 1970-01-01
    • 2020-07-26
    • 2013-09-27
    • 1970-01-01
    • 2022-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多