簡體   English   中英

NodeJS promise(Q).then not named

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM