我想要一个管理mongodb集合的store
js对象,其行为如下:
store.insert(thing); // called from a pubsub system that don't wait the insert to finish
store.get(); // returns a promise that resolves to the things in the collection
// even if called immediately after insert it must contain the last thing inserted
我手动实现了它:
let inserts = 0;
let afterInserts = [];
const checkInsertsFinished = () => {
if (inserts === 0) {
afterInserts.forEach(resolve => resolve());
afterInserts = [];
}
};
const decrementInserts = () => {
inserts -= 1;
checkInsertsFinished();
};
const insertsFinished = () =>
new Promise((resolve) => {
afterInserts.push(resolve);
checkInsertsFinished();
});
const insert = (thing) => {
inserts += 1;
db.collection('mycollection').insertOne(thing).then(decrementInserts);
};
const get = async () => {
await insertsFinished(); // if there are inserts happening, wait for them to finish
return db.collection('mycollection').find({}).toArray();
};
return { insert, get };
我认为有更多的标准方法可以实现这一目标,但我错过了查找库或内置功能的词汇......你会怎么做?
感谢您的建议。
答案 0 :(得分:0)
JavaScript是单线程的,您编写的代码都不能在多个线程上同时运行,因此您应该能够这样做:
let inserting = Promise.resolve(),
startGetting={};
const insert = (thing) => {
startGetting={};//de-reference startGetting
inserting = db.collection('mycollection').insertOne(thing)
return inserting;
};
const get = () => {
const rec = () =>
inserting.then(
_ =>
new Promise(
(resolve,reject)=>{
//the next op is truely async (although I wonder why no promise),
// someone can insert while this is completing
const start=startGetting;
db.collection('mycollection').find({}).toArray(
(err,results)=>
err
? reject(err)
//inserting could have been set to tby the time
// this completed (in theory) so use startGetting reference equality
: startGetting === start
? resolve(results)//while getting nobody inserted
: resolve(rec())
)
})
);
return rec();
};
return { insert, get };