我正在尝试为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
。
我在这里做错了什么想法?就像我说的那样,它正确地检索数据,但我认为异步调用出了问题。感谢
答案 0 :(得分:2)
正如我所想,这些奇怪错误的主要原因是使用for循环和异步调用。为了避免for循环,我决定更多地利用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;
}