【问题标题】:Axios.all in NodeJS failing with 404 errorNodeJS 中的 Axios.all 因 404 错误而失败
【发布时间】:2018-11-30 14:53:20
【问题描述】:

我希望你能帮助我,因为要解决这个问题需要几个小时。我用谷歌搜索了很多并尝试了我找到的所有解决方案,但我一直收到同样的错误。 我试图让轴获取对 API 的请求,该 API 为每页 1 个结果分页,循环遍历所有结果,并使用 promise 数组解决 promise。 我已经验证,没有循环,只收到 1 个请求,一切正常。我已经使用 MongoDB 驱动程序成功写入 MongoDB,并且很好。一旦我引入循环,我就无法得到解决的承诺。我能够 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);
        });
    }
}

我需要一个 JSON 对象数组,以便 insertMany 函数工作。请有人帮助我。我究竟做错了什么?

【问题讨论】:

    标签: javascript node.js mongodb express axios


    【解决方案1】:

    for 循环中,您正在创建一个这样的 URL:https://catfact.ninja/facts/facts?page=1 – 这是不正确的,正确的 URL 应该是 https://catfact.ninja/facts?page=1(只有 facts一次)。

    另外,这里不需要关键字async,应该返回axios.all的结果。

    您的代码的正确版本:

    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;
      });
    }
    

    然后您可以像这样获取数据:

    let arr = await dataArray(5);
    

    以您想要的方式获取实际数据

    从您的 cmets 中,我看到您真正想要的是对从 API 获得的数据进行后处理,最终得到一个仅包含 cat 数据的数组。

    您可以通过使用mapreduce“按摩”数据来做到这一点,如下所示:

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

    注意:为简洁起见,我在此处省略了 console.log 语句。

    • 实际数据作为属性“数据”嵌套在对象内的对象中作为属性“数据”,因此 map 调用会检索该属性
    • 我们得到一个数组数组,每个数组都有一个带有猫数据的对象; reduce 调用将其扁平化为一个简单的 cat 数据数组

    我们得到一个看起来像这样的结果,希望这就是您想要的 ?:

    [
        {
            "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
        }
    ]
    

    【讨论】:

    • 非常感谢......这是编码 15 小时后发生的事情。我真的需要睡觉了......在用你的代码更新后,我可以解决承诺,但数据包括我不想要的标题,我想要的数据嵌套在数据中:[array]你知道如何拉出数组并去掉标题吗?通过一个获取请求,我只使用了 response.data 但它不适用于 promise.all 语法。它回来未定义...谢谢!
    • 添加了答案,您没有指定数据的确切外观。如果这不是您所需要的,希望它能为您指明正确的方向
    • 你太棒了帕特里克。您不仅确切地知道自己在做什么,还知道如何读懂无法表达的行尸走肉编码员的思想!太感谢了。你给了我我需要的东西!!
    【解决方案2】:

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

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

    【讨论】:

    • 感谢您帮助雅各。这对于了解 axios 实际如何推荐使用 .all 非常有帮助
    猜你喜欢
    • 2013-07-15
    • 1970-01-01
    • 2014-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-11
    相关资源
    最近更新 更多