Это довольно ужасный пример, которому вы следуете, но в основном там есть ошибки, по существу составленные из http:///www.google.com
, который создается, поскольку значение в документе отличается от www.google.com
, поэтому вы не получите результат, и этоundefined
при попытке прочитать свойство из пустого массива.
Основные исправления будут заключаться в том, чтобы исправить это, и фактически использовать findOneAndUpdate()
во всех случаях, поскольку это будет атомарно возвращать документ.
var MongoClient = require('mongodb').MongoClient;
var website = {
url: 'http://www.google.com',
visits: 0
};
var findKey = {
url: 'http://www.google.com'
}
MongoClient.connect('mongodb://127.0.0.1:27017/demo', { useNewUrlParser: true }, function(err, client) {
var db = client.db('demo');
if(err) throw err;
var collection = db.collection('websites');
collection.findOneAndUpdate(
findKey, website, { upsert: true },function(err, doc) {
var done = 0;
function onDone(err,doc) {
done++;
console.log("Visits: %s", doc.value.visits);
if (done >= 4) {
collection.drop(function(err) {
client.close();
});
}
}
var incrementVisits = {
'$inc': {
'visits': 1
}
};
var options = { returnOriginal: false };
collection.findOneAndUpdate(findKey, incrementVisits, options, onDone);
collection.findOneAndUpdate(findKey, incrementVisits, options, onDone);
collection.findOneAndUpdate(findKey, incrementVisits, options, onDone);
collection.findOneAndUpdate(findKey, incrementVisits, options, onDone);
});
});
Обратите внимание, что эти "четыре" звонка в конце не разрешаются немедленно.Они просто ставят в очередь асинхронные функции, и нет гарантированного порядка их выполнения.
Но скрипт вернет:
Visits: 1
Visits: 2
Visits: 3
Visits: 4
Вместо этого будет гораздо лучший и современный пример:
const { MongoClient } = require("mongodb");
const uri = "mongodb://localhost:27017/";
const options = { useNewUrlParser: true };
const website = {
url: 'http://www.google.com',
visits: 0
};
const findKey = { url: 'http://www.google.com' };
(async function() {
try {
const client = await MongoClient.connect(uri,options);
const db = client.db('demo');
const collection = db.collection('websites');
await collection.insertOne(website);
var times = 4;
while (times--) {
let doc = await collection.findOneAndUpdate(
findKey,
{ $inc: { visits: 1 } },
{ returnOriginal: false },
);
console.log("Visits: %s", doc.value.visits);
}
await collection.drop();
client.close();
} catch(e) {
console.error(e);
} finally {
process.exit();
}
})()
Поскольку мы фактически await
каждый вызов выполняем в цикле while
, мы гарантируем, что они фактически выполняются последовательно.Мы также await
все, так что код чист и упорядочен, и мы можем просто повесить соединение с базой данных, когда все будет сделано, не дожидаясь ответных вызовов или других методов.