简体   繁体   English

NodeJS中的Axios.all失败并显示404错误

[英]Axios.all in NodeJS failing with 404 error

I hope you can help me because it is HOURS of trying to get this problem resolved. 希望您能为我提供帮助,因为这是尝试解决此问题的时间。 I've googled so much and tried all of the solutions I found, but I keep getting the same error. 我已经在Google上搜索了很多东西,并尝试了所有发现的解决方案,但是我一直遇到同样的错误。 I am trying to make an axis get a request to an API that is paginated for 1 result per page, loop through all of the results, and resolve the promises with the promise array. 我试图使一个轴获得对每页1个结果分页的API的请求,循环遍历所有结果,并使用promise数组解析promise。 I have verified that without the loop, just getting 1 request, everything works. 我已经验证,没有循环,仅收到1个请求,一切正常。 I have successful writing to MongoDB using MongoDB driver and its fine. 我已经成功地使用MongoDB驱动程序写了MongoDB了。 Once I bring the loop in I cannot get the promises to resolve. 一旦陷入循环,我将无法兑现承诺。 I was able to console.log that the promise array does, indeed, have x number of pending promises in them. 我能够console.log看到,promise数组的确确实有x个待处理的promise。

const MongoClient = require('mongodb')
const axios = require('axios');
const url = 'https://catfact.ninja/fact'

let db = null;
let client = null;

//this one works great
const getMetaData = function () {  
    let data = axios.get(url+"s")
    .then(response => {
        return response.data
    }).catch(error => console.log(error));
   return data;
}
//this one will not resolve
const dataArray =  async function (total) {
    let baseUrl = url+"s/facts?page="
    let res =[];    
    let promises = [];
    for (let page = 1; page <= total; page++){
        promises.push(axios.get(baseUrl+page))
    }
    axios.all(promises).then(result => console.log(result))
   //originally i wanted to map the result to an array of json
  //objects, but if i could even get a console.log it would be
 //a win. spread operator not working, Promise.all not working
 //i must have tried 12 different stackoverflow responses from
//other questions. until i can resolve the promises I can't do anything.


    }








exports.connect = async function(url, done) {
    if (db) return done();

   // let data = await getMetaData()
   // let total = data['total']
    let arr = dataArray(5);


    //console.log("arr is "+arr)
    MongoClient.connect(url, {useNewUrlParser: true}, function (err, client){
        if (err) return done(err);
        client = client;
        db = client.db('morefun');    
        /*
        db.collection('catfacts').insertMany(dataArray, function(err, res){
            if (err) throw err;
            console.log("Inserted: " + res.insertedCount);
        })*/
        done();


    });


}

exports.get = function() {
    return db;
}

//make sure this is correct
exports.close = function(done) {
    if (db) {
        client.close(function(err, result) {
            db = null;
            mode = null;
            done(err);
        });
    }
}

I need an array of JSON objects for the insertMany function to work. 我需要一个JSON对象数组才能使insertMany函数起作用。 please someone help me. 请有人帮我。 what am I doing wrong? 我究竟做错了什么?

In the for loop, you are creating a URL like this: https://catfact.ninja/facts/facts?page=1 – this is incorrect, the correct URL should be https://catfact.ninja/facts?page=1 (with facts only once). for循环中,您正在创建如下URL: https://catfact.ninja/facts/facts?page=1 : https://catfact.ninja/facts/facts?page=1 –这是不正确的,正确的URL应该是https://catfact.ninja/facts?page=1事实只有一次)。

Also, the keyword async is not needed here, and you should return the result of axios.all . 另外,这里不需要关键字async ,您应该返回axios.all的结果。

A correct version of your code: 正确的代码版本:

const dataArray = function (total) {
  let baseUrl = url+"s?page="
  let res =[];    
  let promises = [];
  for (let page = 1; page <= total; page++){
    promises.push(axios.get(baseUrl+page))
  }
  return axios.all(promises).then(result => {
    console.log(result);
    return result;
  });
}

You can then get your data like this: 然后,您可以像这样获取数据:

let arr = await dataArray(5);

Getting the actual data the way you want it 以所需方式获取实际数据

From your comments, I see that what you really want is to post-process the data obtained from the API to ultimately get one array that contains only the cat data. 从您的评论中,我看到您真正想要的是对从API获得的数据进行后处理,以最终得到一个仅包含cat数据的数组。

You can do this by “massaging” the data with map and reduce , like this: 您可以通过使用mapreduce来“按摩”数据来完成此操作,如下所示:

return axios
    .all(promises)
    .then(result => result.map(({ data }) => data.data).reduce((curr, acc) => acc.concat(curr), []));

Note: I've left out the console.log statement here for brevity. 注意:为简洁起见,这里省略了console.log语句。

  • The actual data is nested as property 'data' in an object within an object as property 'data', so the map call retrieves that 实际数据作为属性“数据”嵌套在对象内的一个对象中,作为属性“数据”,因此map调用检索该对象
  • We get an array of arrays, each with an object with cat data; 我们得到一个数组数组,每个数组都有一个包含cat数据的对象; the reduce call flattens this to a simple array of cat data reduce调用将其简化为简单的cat数据数组

We get a result that looks like this, which is hopefully what you want 😁: 我们得到的结果看起来像这样,希望是您想要的结果:

[
    {
        "fact": "Cats see six times better in the dark and at night than humans.",
        "length": 63
    },
    {
        "fact": "The ability of a cat to find its way home is called “psi-traveling.” Experts think cats either use the angle of the sunlight to find their way or that cats have magnetized cells in their brains that act as compasses.",
        "length": 220
    },
    {
        "fact": "Cat's urine glows under a black light.",
        "length": 38
    },
    {
        "fact": "There are more than 500 million domestic cats in the world, with approximately 40 recognized breeds.",
        "length": 100
    },
    {
        "fact": "A tomcat (male cat) can begin mating when he is between 7 and 10 months old.",
        "length": 76
    }
]

不确定这是否是答案,但我知道当不使用axios想要完全用于axios的语法时,我遇到了问题。

axios.all([fetch1request(), fetch2request()]).then(axios.spread((fetch1, fetch2 ) => * whatever logic you need. But at this point the requests are complete* })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM