0

我正在尝试获取用户在 Google 日历上的所有日历的所有事件。我首先调用gapi.client.calendar.calendarList.list,然后使用在调用中检索到的 ID 来做到这一点gapi.client.calendar.events.list。然而,这导致了一些非常奇怪的结果。这是代码:

getAllEvents: function() {
        var deferred = $q.defer(),
        // get all calendars that the user has on Google Calendar
        getCalendars = function() {
          gapi.client.load('calendar', 'v3', function() {
              var request = gapi.client.calendar.calendarList.list({});
              request.execute(function(resp) {
                  if(!resp.error) {
                    var calendarIds = [];
                    for(var i = 0; i < resp.items.length; i++) {
                      calendarIds.push(resp.items[i].id);
                    }
                    getEvents(calendarIds);
                  }
                  else {
                    deferred.reject(resp.error);
                  }
              });
          });
        },
        // get all events for each calendar that was found
        getEvents = function(calendarIds) {
          var events = [];

          for(var i = 0; i < calendarIds.length; i++) {
            // bind i to function to allow asynchronous functions inside for loop
            (function(cntr) {
              var request = gapi.client.calendar.events.list({
                calendarId: calendarIds[i]
              });

              request.execute(function(resp) {
                  if(!resp.error) {
                    for(var j = 0; j < resp.items.length; j++) {
                      console.log(j);
                      events.push(resp.items[j]);
                    }
                  }
                  else {
                    deferred.reject(resp.error);
                  }
              });
            })(i);
          }
          console.log(events);
          deferred.resolve(events);
        };

        // login to google API before making calls
        gapi.auth.authorize({ 
              client_id: this.clientId, 
              scope: this.scopes, 
              immediate: true, 
        }, getCalendars);

        return deferred.promise;
      }

这会正确检索日历 ID,甚至可以正确检索所有事件。但是,我认为我执行异步调用的方式会导致一些问题。如果我在内部 for 循环之后console.logevents数组,它有 110 个项目,但长度为 0,并且没有一个项目可以通过它们的索引访问。如果我console.log在 for 循环中有什么东西,它会在console.log(events). 最后,如果 Iconsole.logj内部 for 循环中的值,则这些值将无序记录,例如0...19,然后0...86

有什么想法我在这里做错了吗?就像我说的,它正在正确检索数据,但我认为异步调用出了点问题。谢谢

4

1 回答 1

2

正如我所想,这些奇怪错误的主要原因是使用 for 循环和异步调用。为了避免 for 循环,我决定更多地使用 Angular 的承诺:

  • 获取所有日历,并返回一个承诺
  • 调用以获取所有日历完成后,为所需的每个事件查询创建一个承诺
  • 使用 Angular$q.all使用创建的 Promise 进行所有调用,然后返回找到的所有事件。

这是新代码:

getAllEvents: function() {
        var deferred = $q.defer(),

        // get all calendars that the user has on Google Calendar
        getCalendars = function() {
          var calDeferred = $q.defer();

          gapi.client.load('calendar', 'v3', function() {
              var request = gapi.client.calendar.calendarList.list({});
              request.execute(function(resp) {
                  if(!resp.error) {
                    var calendarIds = [];
                    for(var i = 0; i < resp.items.length; i++) {
                      calendarIds.push(resp.items[i].id);
                    }
                    calDeferred.resolve(calendarIds);
                  }
                  else {
                    calDeferred.reject(resp.error);
                  }
              });
          });

          return calDeferred.promise;
        },
        // get all events for a calendar
        getEvents = function(calendarId) {
          var events = [],
              eventsDeferred = $q.defer();

          var request = gapi.client.calendar.events.list({
            calendarId: calendarId
          });

          request.execute(function(resp) {
              if(!resp.error) {
                for(var j = 0; j < resp.items.length; j++) {
                  events.push(resp.items[j]);
                }
                eventsDeferred.resolve(events);
              }
              else {
                eventsDeferred.reject(resp.error);
              }
          });

          return eventsDeferred.promise;
        },
        getAllEvents = function() {
          getCalendars().then(function (calendarIds) {
            var eventCalls = [];

            // get promise for each calendar event query
            for(var i = 0; i < calendarIds.length; i++) {
              eventCalls.push(getEvents(calendarIds[i]));
            }

            // make all calls to get all events
            $q.all(eventCalls).then(function(results) {
              var aggregatedData = [];

              angular.forEach(results, function (result) {
                  aggregatedData = aggregatedData.concat(result);
              });

              deferred.resolve(aggregatedData);
            });
          },
          function (errorMessage) {
            deferred.reject(errorMessage);
          });
        };

        // login to google API before making calls
        gapi.auth.authorize({ 
              client_id: this.clientId, 
              scope: this.scopes, 
              immediate: true, 
        }, getAllEvents);

        return deferred.promise;
      }
于 2013-11-16T19:06:41.120 回答