如何同步回调代码?

How can I synchronize a callback code?

我必须在 tmp 变量中获取 description,但我不知道如何同步此代码,有人可以帮助我吗?

我们想在日历中呈现联系人用户 first_name,即将标题附加到 user.first_name。所以我们从服务器上抓取所有事件,但是对于每个事件都有预订,预订包含用户 ID 以从 contact_users 抓取用户数据。然后我们需要构造 object 并将其推送到包含所有事件的数组,即 tmp。最后调用 callback 以呈现日历中的事件。

Event.query({
  businessId: $stateParams.businessId
})
.$promise.then(function(events) {
  events.forEach(function(event) {
    var tmpData = {};
    var description = '';
    $http.get('/businesses/'+event.business_id+'/events/'+event.id+'/bookings')
    .then(function(bookings) {
      if(bookings.data) {
        $http.get('/businesses/'+event.business_id+'/contact_users/'+bookings.data[0].people_id)
        .then(function(user) {
          description = user.data.first_name;
        });
      }
    });
    tmpData = {
      eventId: event.id,
      title: description,
      start: event.starts_at,
      end: event.ends_at,
      business_id: event.business_id,
      employment_id: event.employment_id,
      professional_id: event.professional_id,
      service_id: event.service_id,
    };
    tmp.push(tmpData);
  });
  return tmp;
}).then(function(result) {
  callback(tmp);
});

回调与 events 方法中触发的 fullcalendar callback 事件相关。

在处理 Promise 回调时有两个关键概念:

从 Promise 成功回调中返回 会导致下一个 promise 以该值解析。

$q.when().then(function () {
    return 3;
}).then(function (result) {
    // result === 3
});

从 Promise 成功回调中返回 另一个 Promise 有效地替换了现有的 Promise。

$q.when().then(function () {
    return $timeout(function () { return 3 }, 1000);
}).then(function (result) {
    // called 1000ms later
    // result === 3
});

此外,还有一个构造 $q.all(promises) 接受一系列承诺,并且 return 是一个新的承诺,当 promises 全部解决(或其中一个时)被拒绝了)。


我无权访问您的后端,因此我无法对此进行测试,但像这样的东西应该适合您:

Event.query({ businessId: $stateParams.businessId }).$promise
  .then(function (events) {
    // get array of $HttpPromise objects
    var promises = events.map(function (event) {
      return $http.get('/businesses/' + event.business_id + '/events/' + event.id + '/bookings')
        .then(function (response) {
          var bookings = response.data;

          // "transformed" event object
          var evt = {
            eventId: event.id,
            title: '',
            start: event.starts_at,
            end: event.ends_at,
            business_id: event.business_id,
            employment_id: event.employment_id,
            professional_id: event.professional_id,
            service_id: event.service_id
          };

          // each promised is replaced either with a new $HttpPromise...
          if (bookings) {
            return $http.get('/businesses/' + event.business_id + '/contact_users/' + bookings[0].people_id)
              .then(function (response) {
                var user = response.data;

                evt.title = user.first_name;
                return evt;
              });
          }

          // ...or with an immediately resolved event
          return evt;
        })
    });

    // wait for all promises to be resolved
    return $q.all(promises);
  }).then(function (results) {
    // results is an array of transformed events
    callback(results);
  });

旁注:另一种选择是不等待内部 $http 承诺解决,只需 return "incomplete" evt对象。

// launch a promise which updates evt when resolved
if (bookings) {
    $http.get('/businesses/' + event.business_id + '/contact_users/' + bookings[0].people_id)
        .then(function (response) {
            var user = response.data;

            // update evt reference
            evt.title = user.first_name;
        });
}

// immediately resolve with "incomplete" evt
return evt;

Angular 每次解决承诺时都会触发摘要。根据您设置 templates/rendering 的方式,这可能会产生以下效果:首先使用空 title 渲染所有事件,然后在可用时使用 first_name 重新渲染。请注意,这需要您在回调和模板之间的任何地方维护 evt 引用。