简体   繁体   English

NodeJS promise(Q).then not named

[英]NodeJS promise (Q) .then its not called

im trying to do promises in NodeJS with mongodb queries. 我试图用mongodb查询在NodeJS中做诺言。

Mongo library its mongod, i think it return promises. Mongo库是它的mongod,我认为它能兑现承诺。

This is my code: 这是我的代码:

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

Im trying to-> Insert client, then, insert order, then, assign the order _id to the client _id. 我试图->插入客户端,然后插入订单,然后将订单_id分配给客户端_id。 I put the log.debug, but i can only see the 我放了log.debug,但是我只能看到

 log.debug('mondialParser', 'addClient', currentClient);

Other one its not called..Why? 另一个不叫。为什么? This is the correct use for promises? 这是诺言的正确用法吗? Is there any better way? 有什么更好的办法吗?

EDIT: 编辑:

Other way: 另一种方式:

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

    }
};

This execute all the "tasks" but inside w.all resultOrder and resultClient are undefined.. 这将执行所有“任务”,但w.all resultOrder和resultClient内部未定义。

Both of your functions return undefined . 这两个函数都返回undefined You are returning the value from the .then handler correctly, but you are not returning a promise from insertOrder at all: 你是从返回值.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
});

When Q.all gets a non promise argument (in this case undefined ) it casts it to a promise, so you got Q(undefined) twice there. Q.all获得一个non promise参数(在本例中为undefined )时,它将其强制转换为一个promise,因此您在这里得到了Q(undefined)两次。

The core principle to keep in mind is that "a promise represents the result of an asynchronous operation". 要牢记的核心原则是:“承诺代表异步操作的结果”。 This means that it does not need to be executed, you simply need to wait for it to be fulfilled (or rejected). 这意味着不需要执行它,您只需要等待它实现(或拒绝)即可。 The operation is started as soon as you call the method, just like with synchronous code. 就像调用同步代码一样,一旦调用该方法,操作就会开始。

You may, however, wish to be aware that mongod uses the promise library, instead of Q. The two are interoprable though, so this will likely not cause any issues. 您可能,但是,要注意的mongod使用承诺库,而不是问:这两个是interoprable虽然如此,这将有可能不会造成任何问题。 If you want to turn a promise into a Q promise, you can just use var QPromise = Q(nonQPromise); 如果要将承诺转换为Q承诺,则可以使用var QPromise = Q(nonQPromise); .

You need to make sure you always keep returning promises from inside your onFulfilled functions (the ones passed as the first argument to .then ). 你需要确保你始终保持从里面你回来的承诺onFulfilled功能(通过作为第一个参数的那些.then )。 With that in mind, I would re-write your original code as: 考虑到这一点,我将您的原始代码重写为:

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

Note that promises, by default, do not expose their errors, because they can't know that the error will not be handle later. 请注意,默认情况下,promise不会公开其错误,因为它们不知道以后不会处理该错误。 You can fix this by calling .done at the end of your promise chain, which indicates that you don't wish to handle any additional errors. 您可以通过在诺言链的末尾调用.done来解决此问题,这表明您不希望处理任何其他错误。 Both Q and promise support this feature. Q和Promise均支持此功能。

Your second example (which has the advantage of doing some of the work in parallel, can be fixed simply by adding a few extra return statements: 您的第二个示例(具有并行执行某些工作的优势,可以通过添加一些额外的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();

  }
};

This can be further simplified though, by removing the extraneous functions: 但是,通过删除多余的功能,可以进一步简化此操作:

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

  }
};

This still executes both inserts in parallel because each insert is started before we wait for anything. 这仍然并行执行两个插入操作,因为每个插入操作都在我们等待之前开始。 Calling an asynchronous function starts the operation, and returns a promise for the result. 调用异步函数将启动操作,并返回结果的承诺。

If you'd like a more complete tutorial for how promises work, check out: https://www.promisejs.org/ 如果您想要关于承诺如何运作的更完整的教程,请查看: https : //www.promisejs.org/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM