Хобрук: Ваш путь к мастерству в программировании

Обещание NodeJS (Q). Тогда оно не вызывается

я пытаюсь выполнять обещания в NodeJS с запросами mongodb.

Библиотека 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 не определены.


  • Что Q.fcall(promise); должен делать? promise — это обещание, а не функция. 04.06.2014
  • Я думаю, что это выполняет обещание, верно? Ее мои первые обещания использования. 04.06.2014
  • Нет, обещание не представляет задачу, которую вы можете начать. Он представляет значение результата задачи и обычно возвращается при запуске задачи. В вашем случае вы звоните insert. 04.06.2014
  • Под mongod вы подразумеваете эту библиотеку? 04.06.2014
  • @Bergi Берги да, я отредактировал свой код вопроса другим способом ... Но не смог. 04.06.2014
  • Хм. Получаете ли вы какие-либо исключения? Может быть, попробуйте прикрепить обработчики ошибок к каждому вызову. 04.06.2014
  • Нет, я не получаю никаких исключений. Только когда я пытаюсь выполнить последнее обновление, значение объектов параметров не определено. 04.06.2014
  • Хм, это действительно странно. 04.06.2014

Ответы:


1

Основной принцип, о котором следует помнить, заключается в том, что «обещание представляет собой результат асинхронной операции». Это означает, что его не нужно выполнять, нужно просто дождаться его выполнения (или отклонения). Операция запускается, как только вы вызываете метод, как и в случае с синхронным кодом.

Однако вы можете знать, что mongod использует promise вместо Q. Однако они совместимы, поэтому, скорее всего, это не вызовет никаких проблем. Если вы хотите превратить обещание в обещание 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));
  });
}

Обратите внимание, что обещания по умолчанию не раскрывают свои ошибки, потому что они не могут знать, что ошибка не будет обработана позже. Вы можете исправить это, вызвав .done в конце вашей цепочки промисов, что указывает на то, что вы не хотите обрабатывать какие-либо дополнительные ошибки. И Q, и обещание поддерживают эту функцию.

Ваш второй пример (преимущество которого состоит в том, что часть работы выполняется параллельно, можно исправить, просто добавив несколько дополнительных операторов возврата:

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/< /а>

05.06.2014

2

Обе ваши функции возвращают 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 получает аргумент, не являющийся обещанием (в данном случае undefined), он преобразует его в обещание, поэтому вы получили Q(undefined) дважды.

04.06.2014
Новые материалы

Создание кнопочного меню с использованием HTML, CSS и JavaScript
Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

Внедрите OAuth в свои веб-приложения для повышения безопасности
OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

Классы в JavaScript
class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

Как свинг-трейдеры могут использовать ИИ для больших выигрышей
По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

Как построить любой стол
Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

Обзор: Машинное обучение: классификация
Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

Разработка расширений Qlik Sense с qExt
Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..