使用Google API Javascript客户端获取所有日历的所有活动

时间:2013-11-12 20:48:05

标签: javascript angularjs google-calendar-api google-api-js-client

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

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.log events数组,它有110个项目,但长度为0,并且没有任何项目可以通过它们的索引访问。如果我在for循环中有console.log个内容,则会在console.log(events)之后打印。最后,如果我在内部for循环中console.log j的值,则会按顺序记录值,例如0...19,然后0...86

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

1 个答案:

答案 0 :(得分:2)

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

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

这是新代码:

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