环回-“ next()”未在“ beforeRemote”中的正确时间触发?

时间:2018-10-21 17:19:09

标签: node.js loopbackjs

我试图在find方法返回结果之前从远程源更新数据库。我正在尝试对“查找”操作使用“ beforeRemote”方法。它正在更新数据库,但是在返回数据之前不等数据库完成更新。我可以断定,因为第一次对空数据库调用“查找”端点时,结果为空,但是在调用之后检查数据库时,它中就有数据。

这是我的模型类(敏感内容已删除)。

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

我是回环的新手,所以我确定这是一个简单的错误。我做错了什么?

1 个答案:

答案 0 :(得分:0)

使用Promise.all Promise.all

在这种情况下,不应将forEach与异步操作一起使用,因为forEach直到更新完成然后再调用next时才等待。 相反,例如使用map来循环事件并返回更新操作的Promise,以便您可以创建Promise数组并使用 Promise.all 。 在Promise。 then 中,全部调用下一个方法。

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