у меня есть эта модель
const BlockModel = Mongoose.model('blocks', {
height: Number,
size: Number,
time: Number
})
И этот вызов API (hapi.js)
server.route({
method: "GET",
path: "/api/blockinfo",
handler: async (request, h) => {
await BlockModel.deleteMany({})
const { res, payload } = await Wreck.get('https://someurl');
let myJson = JSON.parse(payload.toString()).blocks
// console.info(myJson)
for (let i = 0; i < myJson.length; i++) {
var block = new BlockModel({
height: myJson[i].height,
size: myJson[i].size,
time: myJson[i].time
});
block.save();
}
console.info(BlockModel.find({}))
return BlockModel.find({}); //returns an empty array
}
})
Таким образом, он в основном удаляет содержимое коллекции, а затем загружает в нее новые данные. Я хочу вернуть эту коллекцию, чтобы она отображалась в моем API. Но BlockModel.find({}) возвращает пустую коллекцию, хотя я могу проверить, что коллекция не пуста, если воспользуюсь консолью mongo и проверю
db.blocks.find({})





Добавьте await к звонку save,
await block.save();
Удалите console.info, а также проверьте вызов сохранения await block.save();. Это должно было случиться.
@ShivamPandey, ты имеешь в виду, что ОП должен делать return await BlockModel.find({});?
@ShivamPandey, кроме того, что он упомянул, что у block.save() тоже должно быть ожидание
@GrégoryNEUT Да
Так что это неправильно. Функция является async функцией. Не надо return await. Возврат Promise достаточно хорош. Проблема была с await save и console.info(await BlockModel.find({}))
@ShivamPandey, вы должны отредактировать свой ответ, чтобы правильно исправить проблему OP :)
Пожалуйста, измените свой ответ, проблема была с await block.save(), возврат не должен иметь ожидание
return await aPromise такой же return aPromiseВы можете создавать нужные блоки, используя вставитьмного. Этот метод вернет вам непосредственно недавно вставленные данные.
async(request, h) => {
await BlockModel.deleteMany({});
const {
res,
payload
} = await Wreck.get('https://someurl');
const myJson = JSON.parse(payload.toString()).blocks
// Create new items and save them into the database.
// insertMany returns the added blocks
return BlockModel.insertMany(myJson.map(x => ({
height: x.height,
size: x.size,
time: x.time
})));
}
Если myJson выглядит так:
[{
height,
size,
time,
}]
Вы можете превратить код в:
async(request, h) => {
await BlockModel.deleteMany({});
const {
res,
payload
} = await Wreck.get('https://someurl');
const myJson = JSON.parse(payload.toString()).blocks
// Create new items and save them into the database.
// insertMany returns the added blocks
return BlockModel.insertMany(myJson);
}
Здесь этот подход намного лучше insertMany. ОП должен использовать этот подход.
Попробуй использовать:
await block.save();
// wait to save block before return
// ....
const blocks = await BlockModel.find({})
console.info(blocks)
return blocks;
Я думаю, что ваш код работает нормально (не console.info), потому что вы вызываете:
console.info(BlockModel.find({}))
Он будет регистрировать обещание, а не ожидаемый объект.
Мы сохраняем его в одну переменную, потому что нам не нужно вызывать запрос дважды.
Это решает половину проблемы. Основная проблема связана с асинхронностью block.save();
Странно, в обратке будет работать, но только если я не удалю предыдущую
console.info(await BlockModel.find({})), которую хочу удалить