如何进行同步的forEach循环并向Javascript中的API发出异步请求

时间:2018-09-19 20:34:29

标签: javascript node.js reactjs api

Am尝试使用参数数组创建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)

2 个答案:

答案 0 :(得分:1)

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

optDetails.map()的结果是一个承诺数组。您需要对此使用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?或者您想串联{ {1}}到stateData中已经存在的内容上?


简单版本

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

optDetails

答案 1 :(得分:0)

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

然后,您在Promise.all上调用newPromise-但是newPromise并不是像一个承诺数组那样可迭代的。也许您希望它是optDetails.map()创建的承诺数组的承诺,但是即使如此:您必须在数组本身上立即调用Promise.all,然后再从{{1 }}回调。

您最有可能在寻找

then