[英]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.