Ошибка Axios.all в NodeJS с ошибкой 404 - PullRequest
0 голосов
/ 30 ноября 2018

Я надеюсь, что вы можете помочь мне, потому что это ЧАСЫ, чтобы попытаться решить эту проблему.Я так много гуглил и перепробовал все найденные решения, но получаю одну и ту же ошибку.Я пытаюсь заставить ось получить запрос к API, который разбит на страницы по 1 результату на страницу, просмотреть все результаты и разрешить обещания с помощью массива обещаний.Я проверил, что без цикла, просто получая 1 запрос, все работает.У меня есть успешная запись в MongoDB с использованием драйвера MongoDB и его хорошо.Как только я ввожу петлю, я не могу получить обещания, чтобы решить.Мне удалось console.log, что массив обещаний действительно содержит x ожидающих обещаний.

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.Пожалуйста, кто-нибудь, помогите мне.Что я делаю неправильно?

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

В цикле для вы создаете URL-адрес примерно так: https://catfact.ninja/facts/facts?page=1 - это неверно, правильный URL-адрес должен быть https://catfact.ninja/facts?page=1фактами только один раз).

Кроме того, ключевое слово 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);

Получение фактических данных так, как вы хотите

Из ваших комментариев я вижу, что выдействительно нужно пост-обработать данные, полученные из API, чтобы в итоге получить один массив, который содержит только данные cat.

Вы можете сделать это, «массируя» данные с помощью map и уменьшить , например так:

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

Примечание. Я здесь для краткости опущу здесь выражение console.log.

  • Фактические данные вложеныкак свойство 'data' в объекте внутри объекта как свойство 'data', поэтому вызов map возвращает
  • Мы получаем массивмассивов, каждый с объектом с данными cat; уменьшение вызов сводит это к простому массиву данных кошки
0 голосов
/ 30 ноября 2018

Не уверен, что это ответ, но я знаю, что столкнулся с проблемами, когда не использовал синтаксис axios, который требуется точно для axios all.

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

...