【问题标题】:Getting all events for all calendars with Google API Javascript Client使用 Google API Javascript 客户端获取所有日历的所有事件
【发布时间】:2013-11-25 05:09:54
【问题描述】:

我正在尝试获取用户在 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

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

【问题讨论】:

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


    【解决方案1】:

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

    • 获取所有日历,并返回一个承诺
    • 获取所有日历的调用完成后,为所需的每个事件查询创建一个承诺
    • 使用 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;
          }
    

    【讨论】:

    • 旁注,知道有人必须手动实现这一点并花费 n 个 API 调用,而不是在用户对象上使用 getAllEvents(),我感到非常难过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    • 2021-03-05
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    相关资源
    最近更新 更多