首页 > 解决方案 > loopback - “next()”没有在“beforeRemote”中的正确时间触发?

问题描述

我正在尝试在 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);
  });
};

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

标签: node.jsloopbackjs

解决方案


使用 Promise.all Promise.all

在更新的情况下,您不应该将 forEach 与异步操作一起使用,因为 forEach 在更新完成之前不会等待,然后调用 next。而是使用 map 例如循环事件并返回更新操作的承诺,以便您可以创建承诺数组并使用Promise.all。在Promise.all 的 then 中调用 next 方法

    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,您无需调用 next loopback 即可为您处理。

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

推荐阅读