loopback - "next ()" не запускается в нужное время в "beforeRemote"? - PullRequest
0 голосов
/ 21 октября 2018

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

Вот моя моделькласс (удалены важные данные).

'use strict';
var Cronofy = require('cronofy');
var _ = require('lodash');

module.exports = function (Event) {

  // remote method before hook
  Event.beforeRemote('find', function (ctx, unused, next) {
    var client = new Cronofy({
      access_token: 'secret-token',
    });

    var options = {
      from: "2018-10-15",
      to: "2018-11-15",
      tzid: 'Etc/UTC'
    };


    client.readEvents(options)
      .then(function (response) {
        var returnedEvents = response.events;
        var events = _.filter(returnedEvents, function(o){
          return !_.isEmpty(o.summary) && !_.isEmpty(o.event_uid) && !_.isEmpty(o.start) && !_.isEmpty(o.end);
        });

        events.forEach(element => {
          Event.upsertWithWhere({
              sourceType: "external-source-a",
              sourceID: element.event_uid
            }, {
              sourceType: "external-source-a",
              sourceID: element.event_uid,
              summary: element.summary,
              description: element.description,
              start: element.start,
              end: element.end,
              recurring: element.recurring
            },
            function (err, model) {
              if (err) {
                console.log(err);
              }
              //console.log(model);
            }
          );
        });
        next();
      }).catch(console.log);
  });
};

Я новичок в loopback, поэтому я уверен, что это простая ошибка.Что я сделал не так?

1 Ответ

0 голосов
/ 21 октября 2018

используйте Promise.all Promise.all

В вашем случае не следует использовать forEach с асинхронной операцией, поскольку forEach не будет ждать до обновлениязакончен, а затем позвоните дальше.Вместо этого используйте карту, например, чтобы зациклить события и вернуть обещание операции обновления, чтобы вы могли создать массив обещаний и использовать Promise.all затем в Promise.all вызовите следующий метод.

    module.exports = function (Event) {

    // remote method before hook
    Event.beforeRemote('find', function (ctx, unused, next) {
      var client = new Cronofy({
        access_token: 'secret-token',
      });

      var options = {
        from: "2018-10-15",
        to: "2018-11-15",
        tzid: 'Etc/UTC'
      };

      client.readEvents(options)
        .then(function (response) {
          var returnedEvents = response.events;
          var events = _.filter(returnedEvents, function(o){
            return !_.isEmpty(o.summary) && !_.isEmpty(o.event_uid) && !_.isEmpty(o.start) && !_.isEmpty(o.end);
          });
          const updatepromises = events.map((element) => {
            return Event.upsertWithWhere({
              sourceType: "external-source-a",
              sourceID: element.event_uid
            }, {
                sourceType: "external-source-a",
                sourceID: element.event_uid,
                summary: element.summary,
                description: element.description,
                start: element.start,
                end: element.end,
                recurring: element.recurring
              });
          }); 
          return Promise.all(updatepromises); 

        })
        .then((result) => next())
        .catch(console.log);
    });
  };

Или вы можете использовать async / await async / await , который более читабелен, и вам не нужно вызывать следующий цикл, который позаботится об этом за вас.

    module.exports = function (Event) {
  // remote method before hook
  Event.beforeRemote('find', async function (ctx, unused) {
    var client = new Cronofy({
      access_token: 'secret-token',
    });
    var options = {
      from: "2018-10-15",
      to: "2018-11-15",
      tzid: 'Etc/UTC'
    };
    var response = await client.readEvents(options);
    var returnedEvents = response.events;
    var events = _.filter(returnedEvents, function (o) {
      return !_.isEmpty(o.summary) && !_.isEmpty(o.event_uid) && !_.isEmpty(o.start) && !_.isEmpty(o.end);
    });
    const updatepromises = events.map((element) => {
      return Event.upsertWithWhere({
        sourceType: "external-source-a",
        sourceID: element.event_uid
      }, {
          sourceType: "external-source-a",
          sourceID: element.event_uid,
          summary: element.summary,
          description: element.description,
          start: element.start,
          end: element.end,
          recurring: element.recurring
        });
    });
    await Promise.all(updatepromises);
  });
};
...