Javascript Node.js MongoDB利用承诺进行MongoDB方法调用
编辑 所以我正在创建一个电子商务网站,我遇到了一些障碍。此后,我更新了我的代码,使其更清晰、更易于阅读,并在某种程度上指出了问题的根源(尽管可能还有更多)。以下是更新的代码:Javascript Node.js MongoDB利用承诺进行MongoDB方法调用,javascript,node.js,mongodb,Javascript,Node.js,Mongodb,编辑 所以我正在创建一个电子商务网站,我遇到了一些障碍。此后,我更新了我的代码,使其更清晰、更易于阅读,并在某种程度上指出了问题的根源(尽管可能还有更多)。以下是更新的代码: StoreDB.prototype.addOrder = function(order) { console.log('addOrder'); return this.connected.then(function(db) { console.log(order); var
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
的函数调用将等待对Collections.find的方法调用完成,然后再进行解析(返回订单数组)。由于某种原因,它返回的是空数组
任何帮助都将不胜感激 不确定第一个块和第二个块之间的关系,但在第一个块中:
函数插入(订单、订单、数据库){
返回新承诺(功能(解决、拒绝){
log(“将订单插入订单集合”);
命令。插入(命令);
解决(db.托收(“订单”);
});
}
乍一看,它似乎是orders。insert(order)
是异步的,但您不会等到它完成后再解析
您可以使函数异步,也可以
等待订单。插入(订单);
或
订单。插入(订单)
.然后(()=>解析(db.collection('orders'))
但是,在承诺中包含Collections.insert方法是否会使该方法调用异步 是的,
Collections.insert
是隐式异步的,因为它返回一个承诺。我说的是显式地声明它async
,这样您就可以等待
函数体中的其他异步调用。注意在开始和等待订单时添加了async
。insert()
异步函数插入(顺序、顺序、数据库){
返回新承诺(功能(解决、拒绝){
log(“将订单插入订单集合”);
等待订单。插入(订单);
解决(db.托收(“订单”);
});
}
如果您不等待订单。插入
(通过等待
或。然后
)您正在调用插入
,并立即返回db.collection
调用,这会创建一个竞争条件,新订单可能尚未插入。新订单有可能在那里,但似乎不太可能,而且也不会可靠地在那里
这里也没有必要创造新的承诺db.collection
已返回承诺。只需返回您已经拥有的:
函数插入(订单、订单、数据库){
log(“将订单插入订单集合”);
退货订单。插入(订单)
然后(()=>db.collection('orders');
}
看看这个示例代码片段。我模拟了orders.insert
和db.collection
方法
//mock orders.insert
常量命令={
插入:async()=>{
返回新承诺((解决)=>{
//等一下,然后解决问题
设置超时(解析,1000);
});
}
}
//模拟数据库集合
常数db={
集合:async()=>{
返回新承诺((解决)=>{
//请稍等片刻,然后使用模拟数据进行解析
setTimeout(()=>resolve(['foo','bar','baz']),1000);
});
}
}
函数插入(订单、订单、数据库){
退货订单。插入(订单)
然后(()=>db.collection('orders');
}
//同上,但使用异步/等待
异步函数insertAsync(订单、订单、数据库){
等待订单。插入(订单);
返回等待数据库收款(“订单”);
}
函数go(){
//使用当时
插入(null,orders,db)。然后插入(console.log);
//使用异步/等待;
insertAsync(null,orders,db).then(console.log);
}
go()
但是在承诺中没有方法Collections.insert会使该方法调用异步吗?我尝试了你的解决方案,但没有解决问题:(我在上一个示例中修复了一个错误。现在传递然后传递一个函数。哎呀。这可能仍然是错误的。今天解决问题后,我会仔细看一看。用一些观察结果和一些示例代码更新答案。
return insert(order, orders, db)
.then(function(updatedOrdersList) {
return obtainOrders(updatedOrdersList);
})
.then(function(orderList) {
return updateProducts(orderList, products);
})