我正在尝试获取json,并与mongodb检查是否存在重复项(如果不存在),然后将数据插入mongodb。
问题在于循环非常快,无需等待重复的检查和插入。
我在做什么错了?
const fetch = require('node-fetch');
var MongoClient = require('mongodb').MongoClient;
async function fetchPhotos() {
MongoClient.connect("mongodb://localhost:27017", async function (err, dbo) {
const db = dbo.db('mydb')
if (err) throw err;
for (var i = 1; i < 100; i++) {
await fetch(`domain.com/?page=${i}`)
.then(res => res.json())
.then((response) => {
response.forEach(photo => {
console.log("checking if there is duplicate: " + photo.id);
var exists = db.collection("photos").countDocuments({"id": photo.id}, {limit: 1});
if (exists === 1) {
console.log("dupl found, next!");
} else {
db.collection("photos").insertOne(photo, function (err, res) {
if (err) throw err;
console.log("1 document inserted");
});
}
});
});
}
});
}
module.exports.fetchPhotos = fetchPhotos;
答案 0 :(得分:2)
循环中异步代码存在一些问题。
.forEach()
循环不等待await
。如果要让它等待for
,则必须使用while
循环或await
循环。await
上使用db.collection("photos").countDocuments({"id": photo.id}, {limit: 1});
。await
上使用db.collection("photos").insertOne(photo)
。您可以重组整个内容,以使用数据库的Promise接口,然后通过照片对迭代进行排序,并简化如下操作:
const fetch = require('node-fetch');
var MongoClient = require('mongodb').MongoClient;
async function fetchPhotos() {
const dbo = await MongoClient.connect("mongodb://localhost:27017");
const db = dbo.db('mydb');
for (let i = 1; i < 100; i++) {
let response = await fetch(`http://example.com/?page=${i}`);
let data = await response.json();
for (let photo of data) {
console.log("checking if there is duplicate: " + photo.id);
let cnt = await db.collection("photos").countDocuments({"id": photo.id}, {limit: 1});
if (cnt > 0) {
console.log("dupl found, next!");
} else {
await db.collection("photos").insertOne(photo);
console.log("photo inserted");
}
}
}
}
// caller of fetchPhotos() gets a promise that tells you if the
// operation completed or had an error
module.exports.fetchPhotos = fetchPhotos;