[英]Node.js MongoDB Utilizing promises to make MongoDB method calls
編輯
所以我正在創建一個電子商務網站,但遇到了一些障礙。 從那以后,我更新了我的代碼,使其更清晰、更易於閱讀,並且我在一定程度上指出了我的問題的根源(盡管可能還有更多)。 這是更新后的代碼:
StoreDB.prototype.addOrder = function(order) {
console.log('addOrder');
return this.connected.then(function(db) {
console.log(order);
var orders = db.collection('orders');
var products = db.collection('products');
return insert(order, orders, db)
.then(function(updatedOrdersList) {
return obtainOrders(updatedOrdersList);
})
.then(function(orderList) {
return updateProducts(orderList, products);
})
.catch((err) => console.log('There was an issue in the promise chain\n' + err));
});
}
function insert(order, orders, db) {
return new Promise(function(resolve, reject) {
console.log('Inserting order into orders collection');
orders.insert(order);
resolve(db.collection('orders'));
});
}
function obtainOrders(orders) {
return new Promise(function(resolve, reject) {
console.log('Obtaining orders');
var orderList = orders.find({}).toArray();
resolve(orderList);
});
}
function updateProducts(orderList, products) {
return new Promise(function(resolve, reject) {
console.log('Getting the products that match the cart')
var promises = [];
var promises2 = [];
console.log('orderList', orderList);
for (var item in orderList[0].cart) {
console.log('item', item);
promises.push(products.find({$and : [{"_id" : item}, {"quantity" : {$gte: 0}}]}).toArray());
}
Promise.all(promises)
.then(() => {
console.log('Updating the cart quantity')
for (var i = 0; i < promises.length; i++) {
console.log(promises);
// console.log(productList[item], productList[item]._id, productList[item].quantity, cart);
promises2.push(products.update({"_id" : productList[item]._id}, {$set :{"quantity" : (productList[item].quantity - cart[productList[item]._id])}}));
promises2.push(products.find({}).toArray());
Promise.all(promises2)
.then(() => promises[promises2.length-1]);
}
});
});
}
似乎在承諾鏈中調用obtainOrders
時,它返回一個空數組。 我不太確定為什么要這樣做,因為在鏈中:
return insert(order, orders, db)
.then(function(updatedOrdersList) {
return obtainOrders(updatedOrdersList);
})
.then(function(orderList) {
return updateProducts(orderList, products);
})
上面對obtainOrders
的函數調用等待對 Collections.find 的方法調用完成,然后再解析(返回訂單數組)。 它返回一個空數組的某種原因。
任何幫助將不勝感激!
不確定第一個塊和第二個塊之間的關系是什么,但在第一個塊中:
function insert(order, orders, db) {
return new Promise(function(resolve, reject) {
console.log('Inserting order into orders collection');
orders.insert(order);
resolve(db.collection('orders'));
});
}
乍一看,好像orders.insert(order)
是異步的,但您並不是在等待它完成后再解析。
您可以使函數異步和
await orders.insert(order);
要么
orders.insert(order)
.then(() => resolve(db.collection('orders')))
但是,在 promise 中使用方法 Collections.insert 不會使該方法調用異步嗎?
是的, Collections.insert
是隱式異步的,因為它返回一個 Promise。 我說的是顯式聲明它是async
的,這樣你就可以await
函數體中的其他異步調用。 請注意在開始時添加了async
和await orders.insert()
。
async function insert(order, orders, db) {
return new Promise(function(resolve, reject) {
console.log('Inserting order into orders collection');
await orders.insert(order);
resolve(db.collection('orders'));
});
}
如果您不 await orders.insert
(通過await
或.then
),您將調用insert
並立即返回db.collection
調用,這會創建一個競爭條件,新訂單可能尚未插入。 新訂單可能存在,但似乎不太可能,而且不會可靠地存在。
也無需在此處創建新的 Promise。 db.collection
已經返回一個 Promise。 只需返回您已有的那個:
function insert(order, orders, db) {
console.log('Inserting order into orders collection');
return orders.insert(order)
.then(() => db.collection('orders'));
}
看看這個示例代碼片段。 我模擬了orders.insert
和db.collection
方法。
// mock orders.insert const orders = { insert: async() => { return new Promise((resolve) => { // wait a second then resolve setTimeout(resolve, 1000); }); } } // mock db.collection const db = { collection: async() => { return new Promise((resolve) => { // wait a second then resolve with mock data setTimeout(() => resolve(['foo', 'bar', 'baz']), 1000); }); } } function insert(order, orders, db) { return orders.insert(order).then(() => db.collection('orders')); } // same as above, but with async/await async function insertAsync(order, orders, db) { await orders.insert(order); return await db.collection('orders'); } function go() { // using then insert(null, orders, db).then(console.log); // using async/await; insertAsync(null, orders, db).then(console.log); } go();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.