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);
})