代码之家  ›  专栏  ›  技术社区  ›  Amanda Kitson

loopback-“next()”未在“beforeremote”中的正确时间触发?

  •  2
  • Amanda Kitson  · 技术社区  · 8 年前

    我正在尝试在find方法返回结果之前从远程源更新数据库。我正在尝试对“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);
      });
    };
    

    我是新来的回送,所以我相信这是一个简单的错误。我做错了什么?

    1 回复  |  直到 8 年前
        1
  •  0
  •   Tarek Essam    8 年前

    使用承诺 Promise.all

    在您的案例中,不应该将foreach与异步操作一起使用更新,因为foreach将不等待更新完成,然后调用next。 例如,使用map来循环事件并返回更新操作的promise,这样您就可以创建promise数组并使用 承诺所有 . 在 然后 都调用下一个方法。

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