Я создал API, используя MongoDB и ExpressJS.Я делаю некоторые манипуляции с объектом в коллекции, а затем сразу же получаю его с помощью вызова GET.
post('/cars/1/wheels', {}...)
.delete('/cars/1/doors/1')
.delete('/cars/1/doors/2')
.get('/cars/1')
Я создал REST-Api с использованием асинхронных функций и добавил await
перед всемиманипулирование MongoDB
звонками.
Однако, когда автомобильный объект извлекается из коллекции автомобилей выше, он иногда не является текущим объектом с манипуляциями (он устарел и будет содержать две двери, например).Это довольно непредсказуемо.Когда я проверяю в базе данных все манипуляции прошли через.
Может ли быть так, что MongoDB возвращает кэшированную версию объекта в коллекции?Можно ли заставить MongoDB манипулировать и заставить его обновить кеш?
Редактировать:
Мне трудно изолировать проблему, и я даже не могу найтидетерминированный способ воспроизвести проблему, поэтому я не могу создать минимально работоспособный пример.Проблема возникает, и когда я снова делаю то же самое, она не возникает.
Приведенный выше текст был просто иллюстративным примером, это то, чем я на самом деле занимаюсь.Я делаю три удаления в быстрой последовательности, а затем получаю редактор следующим образом:
delete(/api/editors/editorId/editor-files/file1.png)
.then(data =>
delete(/api/editors/editorId/editor-files/file2.png)
)
.then(data =>
delete(/api/editors/editorId/editor-files/file3.png)
)
.then(data =>
get(/api/editors/editorId)
)
Это часть кода сервера
.delete('/api/editors/:editorId/editor-files/:name', async function (req, res, next) {
const editor = await dbo.collection("editors").findOne({
_id: ObjectId(req.params.editorId)
})
if(!req.user || req.user._id.toString() !== editor.authorId) return res.send({needLogin:true})
const fileInfo = editor.editedArticle.uploadedFiles.find( file => file.name === req.params.name )
// Delete binary
await dbo.collection('files').deleteOne({
_id: ObjectId(fileInfo.mediaId)
})
// Delete file info
await dbo.collection("editors").updateOne(
{_id: ObjectId(req.params.editorId)},
{
$pull: { 'editedArticle.uploadedFiles': { name:req.params.name } },
},
)
await updateArticleCardThumbnail(req.params.editorId, dbo)
res.send({})
})
async function updateArticleCardThumbnail(editorId, dbo) {
const editor = await dbo.collection("editors").findOne({
_id: ObjectId(editorId)
})
const uploadedFiles = editor.editedArticle.uploadedFiles
let base64 = await getArticleCardThumbnailBase64FromUploadedFiles(uploadedFiles, dbo)
await dbo.collection('editors').updateOne(
{_id: ObjectId(editorId),},
{$set: {
'editedArticle.cardThumbnailBase64' : base64
}}
)
}
async function getArticleCardThumbnailBase64FromUploadedFiles(uploadedFiles, dbo) {
let images = uploadedFiles.filter( f => /png|jpg|jpeg|gif|svg|bmp/ig.test(f.mimetype))
let imageNameBackground = images.find( f => /^thumbnail\..*$/.test(f.name))
let backgroundImage = imageNameBackground || images[0]
let base64
if(backgroundImage) {
const imageWithBinary = await dbo.collection("files").findOne({ _id: ObjectId(backgroundImage.mediaId) })
const buffer = await sharp(imageWithBinary.data.buffer).resize(
500, 500, {
fit: 'inside',
}
).toBuffer()
base64 = `data:${backgroundImage.mimetype};base64,${buffer.toString('base64')}`
}
return base64
}
И в конечной точке GET япросто получаю редактор с: db.collection("editors").find(filter).toArray()
Я зарегистрировал запросы, так что я знаю, что удаление возвращается до получения.Но editor.editedArticle.uploadedFiles
будет содержать некоторые старые загруженные файловые модели.Если я подожду пару секунд или обновлю страницу, все будет согласовано.
Возможно, это связано с неправильным использованием async/await
в конечной точке удаления, указанной выше?Я где-то неправильно понял асинхронный / ожидающий код?
Редактировать 2: Удален псевдокод, добавлены фактические вызовы API, изменен заголовок и текст.