希望您能为我提供帮助,因为这是尝试解决此问题的时间。我已经在Google上搜索了很多东西,并尝试了所有发现的解决方案,但是我一直遇到同样的错误。 我试图使一个轴获得对每页1个结果分页的API的请求,循环遍历所有结果,并使用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函数起作用。请有人帮我。我究竟做错了什么?
答案 0 :(得分:1)
在 for 循环中,您正在创建如下所示的URL:https://catfact.ninja/facts/facts?page=1
–这是不正确的,正确的URL应该为https://catfact.ninja/facts?page=1
(带有 facts < / em>仅一次)。
此外,此处不需要关键字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和reduce“按摩”数据来做到这一点,就像这样:
return axios
.all(promises)
.then(result => result.map(({ data }) => data.data).reduce((curr, acc) => acc.concat(curr), []));
注意:为了简洁起见,这里省略了console.log语句。
我们得到的结果看起来像这样,希望是您想要的:
[
{
"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
}
]
答案 1 :(得分:0)
不确定这是否是答案,但我知道我在不使用axios想要完全用于axios的语法时遇到了问题。
axios.all([fetch1request(), fetch2request()]).then(axios.spread((fetch1, fetch2 ) => * whatever logic you need. But at this point the requests are complete* })