[英]NodeJS promise (Q) .then its not called
我試圖用mongodb查詢在NodeJS中做諾言。
Mongo庫是它的mongod,我認為它能兌現承諾。
這是我的代碼:
var dbOrders = mongo(db.serverConfig.name + "/" + db.databaseName, ['orders']);
var dbClients = mongo(db.serverConfig.name + "/" + db.databaseName, ['clients']);
var promise;
if (order.Order.Nif === "") {
var newClient = {
name: order.Order.Asegurado,
ni: order.Order.Nif,//Never used..
address: order.Order.Direccion,
city: order.Order.Poblacion,
province: order.Order.Provincia,
phone: order.Order.Telefonos,
cp: order.Order.CodigoPostal
};
promise = dbClients.clients.insert(newClient).then(function (currentClient) {
log.debug('mondialParser', 'addClient', currentClient);
dbOrders.orders.insert(order.Order).then(function (orderId) {
log.debug('mondialParser', 'addOrder', orderId);
dbClients.clients.update({_id: new ObjectID(currentClient)}, {$push: {dataOrders: orderId}}).then(function () {
log.debug('assignOrder', orderId, currentClient);
});
});
});
Q.fcall(promise);
我試圖->插入客戶端,然后插入訂單,然后將訂單_id分配給客戶端_id。 我放了log.debug,但是我只能看到
log.debug('mondialParser', 'addClient', currentClient);
另一個不叫。為什么? 這是諾言的正確用法嗎? 有什么更好的辦法嗎?
編輯:
另一種方式:
var parseMondial = function (db, order, log) {
"use strict";
var dbOrders = mongo(db.serverConfig.name + "/" + db.databaseName, ['orders']);
var dbClients = mongo(db.serverConfig.name + "/" + db.databaseName, ['clients']);
if (order.Order.Nif === "") {
var newClient = {
name: order.Order.Asegurado,
ni: order.Order.Nif,//Never used..
address: order.Order.Direccion,
city: order.Order.Poblacion,
province: order.Order.Provincia,
phone: order.Order.Telefonos,
cp: order.Order.CodigoPostal
};
var insertClient = function () {
dbClients.clients.insert(newClient).then(function (result) {
log.debug('mondialParser', 'addClient', result);
return result;
});
};
var insertOrder = function () {
dbOrders.orders.insert(order.Order).then(function(result) {
log.debug('mondialParser', 'addOrder', result);
return result;
});
};
Q.all([insertOrder(), insertClient()]).spread(function (resultOrder, resultClient) {
dbClients.clients.update({_id: new ObjectID(resultClient)}, {$push: {dataOrders: resultOrder}}).then(function () {
log.debug('assignOrder', resultOrder, resultClient);
});
}).done();
}
};
這將執行所有“任務”,但w.all resultOrder和resultClient內部未定義。
這兩個函數都返回undefined
。 你是從返回值.then
處理正確,但不必返回從承諾insertOrder
都:
var insertClient = function () {
// note the return
return dbClients.clients.insert(newClient).then(function (result) {
log.debug('mondialParser', 'addClient', result);
return result;
});
};
var insertOrder = function () {
//note the return
return dbOrders.orders.insert(order.Order).then(function(result) {
log.debug('mondialParser', 'addOrder', result);
return result;
});
};
Q.all([insertOrder(),insertClient()]).spread(function(order,client){
// access here
});
當Q.all
獲得一個non promise參數(在本例中為undefined
)時,它將其強制轉換為一個promise,因此您在這里得到了Q(undefined)
兩次。
要牢記的核心原則是:“承諾代表異步操作的結果”。 這意味着不需要執行它,您只需要等待它實現(或拒絕)即可。 就像調用同步代碼一樣,一旦調用該方法,操作就會開始。
您可能,但是,要注意的mongod使用承諾庫,而不是問:這兩個是interoprable雖然如此,這將有可能不會造成任何問題。 如果要將承諾轉換為Q承諾,則可以使用var QPromise = Q(nonQPromise);
。
你需要確保你始終保持從里面你回來的承諾onFulfilled
功能(通過作為第一個參數的那些.then
)。 考慮到這一點,我將您的原始代碼重寫為:
var dbOrders = mongo(db.serverConfig.name + "/" + db.databaseName, ['orders']);
var dbClients = mongo(db.serverConfig.name + "/" + db.databaseName, ['clients']);
var promise;
if (order.Order.Nif === "") {
var newClient = {
name: order.Order.Asegurado,
ni: order.Order.Nif,//Never used..
address: order.Order.Direccion,
city: order.Order.Poblacion,
province: order.Order.Provincia,
phone: order.Order.Telefonos,
cp: order.Order.CodigoPostal
};
promise = Q(dbClients.clients.insert(newClient).then(function (currentClient) {
log.debug('mondialParser', 'addClient', currentClient);
return dbOrders.orders.insert(order.Order).then(function (orderId) {
log.debug('mondialParser', 'addOrder', orderId);
return dbClients.clients.update({_id: new ObjectID(currentClient)}, {$push: {dataOrders: orderId}}).then(function () {
log.debug('assignOrder', orderId, currentClient);
});
});
}));
// optionally call promise.done to expose any errors:
promise.done(function () {
log.debug('operations complete');
}, function (err) {
log.debug('operations failed ' + (err.stack || err));
});
}
請注意,默認情況下,promise不會公開其錯誤,因為它們不知道以后不會處理該錯誤。 您可以通過在諾言鏈的末尾調用.done
來解決此問題,這表明您不希望處理任何其他錯誤。 Q和Promise均支持此功能。
您的第二個示例(具有並行執行某些工作的優勢,可以通過添加一些額外的return語句來解決:
var parseMondial = function (db, order, log) {
"use strict";
var dbOrders = mongo(db.serverConfig.name + "/" + db.databaseName, ['orders']);
var dbClients = mongo(db.serverConfig.name + "/" + db.databaseName, ['clients']);
if (order.Order.Nif === "") {
var newClient = {
name: order.Order.Asegurado,
ni: order.Order.Nif,//Never used..
address: order.Order.Direccion,
city: order.Order.Poblacion,
province: order.Order.Provincia,
phone: order.Order.Telefonos,
cp: order.Order.CodigoPostal
};
var insertClient = function () {
return dbClients.clients.insert(newClient).then(function (result) {
log.debug('mondialParser', 'addClient', result);
return result;
});
};
var insertOrder = function () {
return dbOrders.orders.insert(order.Order).then(function(result) {
log.debug('mondialParser', 'addOrder', result);
return result;
});
};
Q.all([insertOrder(), insertClient()]).spread(function (resultOrder, resultClient) {
return dbClients.clients.update({_id: new ObjectID(resultClient)}, {$push: {dataOrders: resultOrder}}).then(function () {
log.debug('assignOrder', resultOrder, resultClient);
});
}).done();
}
};
但是,通過刪除多余的功能,可以進一步簡化此操作:
var parseMondial = function (db, order, log) {
"use strict";
var dbOrders = mongo(db.serverConfig.name + "/" + db.databaseName, ['orders']);
var dbClients = mongo(db.serverConfig.name + "/" + db.databaseName, ['clients']);
if (order.Order.Nif === "") {
var newClient = {
name: order.Order.Asegurado,
ni: order.Order.Nif,//Never used..
address: order.Order.Direccion,
city: order.Order.Poblacion,
province: order.Order.Provincia,
phone: order.Order.Telefonos,
cp: order.Order.CodigoPostal
};
var resultOrderPromise = dbOrders.orders.insert(order.Order).then(function (result) {
log.debug('mondialParser', 'addOrder', result);
return result;
});
var resultClientPromise = dbClients.clients.insert(newClient).then(function (result) {
log.debug('mondialParser', 'addClient', result);
return result;
});
Q.all([resultOrderPromise, resultClientPromise]).spread(function (resultOrder, resultClient) {
return dbClients.clients.update({_id: new ObjectID(resultClient)}, {$push: {dataOrders: resultOrder}}).then(function () {
log.debug('assignOrder', resultOrder, resultClient);
});
}).done();
}
};
這仍然並行執行兩個插入操作,因為每個插入操作都在我們等待之前開始。 調用異步函數將啟動操作,並返回結果的承諾。
如果您想要關於承諾如何運作的更完整的教程,請查看: https : //www.promisejs.org/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.