我正在使用javascript和skydrive API编写网站。
这是我的代码:
var clientId = '00000000400FFB5A';
var redirectUri = "http://milmantasimmigration.com/skydrive/test/test.html";
WL.init({
client_id: clientId,
redirect_uri: redirectUri
});
WL.Event.subscribe("auth.login", onLogin);
WL.Event.subscribe("auth.sessionChange", onSessionChange);
var session;
var companyFolders;
var reportFolders;
var reports;
session = WL.getSession();
if (session) {
log("You are already signed in!");
getCompanyFolders();
} else {
WL.login({
scope: "wl.signin"
});
}
function onLogin() {
var session = WL.getSession();
if (session) {
log("You are signed in!");
}
}
function onLogout() {
WL.logout();
log("You are logged out!");
}
function onSessionChange() {
var session = WL.getSession();
if (session) {
log("Your session has changed.");
}
}
function getCompanyFolders() {
var getCompanyFoldersDeferred = $.Deferred();
WL.api({
path: "/me/skydrive/shared",
method: "GET"
}).then(
function(response) {
companyFolders = [];
reportFolders = [];
reports = [];
for (var i = 0; i < response.data.length; i++) {
if (response.data[i].type == "folder") {
companyFolders.push(response.data[i]);
getReportFolders(response.data[i].id + "/files/", companyFolders.length - 1);
}
}
$.when.apply($, companyFolders).done(function() {
getCompanyFoldersDeferred.resolve();
});
}, function(response) {
log("Cannot get files and folders: " + JSON.stringify(response.error).replace(/,/g, ",\n"));
});
return getCompanyFoldersDeferred.promise();
}
function getReportFolders(path, index1) {
var getReportFoldersDeferred = $.Deferred();
//var index2 = 0;
WL.api({
path: path,
method: "GET"
}).then(
function(response) {
reportFolders[index1] = [];
reports[index1] = [];
for (var i = 0; i < response.data.length; i++) {
if (response.data[i].type == "folder") {
reportFolders[index1].push(response.data[i]);
//index2++;
getReports(response.data[i].id + "/files/", index1, reportFolders[index1].length - 1);
}
}
$.when.apply($, reportFolders).done(function() {
getReportFoldersDeferred.resolve();
});
}, function(response) {
log("Cannot get files and folders: " + JSON.stringify(response.error).replace(/,/g, ",\n"));
});
return getReportFoldersDeferred.promise();
}
function getReports(path, index1, index2) {
var getReportsDeferred = $.Deferred();
//var index3 = 0;
WL.api({
path: path,
method: "GET"
}).then(
function(response) {
reports[index1][index2] = [];
for (var i = 0; i < response.data.length; i++) {
if (response.data[i].type == "file") {
reports[index1][index2].push(response.data[i]);
//index3++;
}
}
$.when.apply($, reports).done(function() {
getReportsDeferred.resolve();
});
}, function(response) {
log("Cannot get files and folders: " + JSON.stringify(response.error).replace(/,/g, ",\n"));
});
return getReportsDeferred.promise();
}
getCompanyFolders().done(function() {
showReportsHTML();
});
function showReportsHTML() {
for (var i = 0; i < companyFolders.length; i++) {
for (var j = 0; j < reportFolders[i].length; j++) {
for (var k = 0; k < reports[i][j].length; k++) {
alert(reports[i][j][k].name);
}
}
}
}
function log(x) {
alert(x);
}
这两行
getCompanyFolders();
showReportsHTML();
在getCompanyFolders()函数完成其作业后,一个接一个地执行函数。但showReportsHTML()是在getCompanyFolders()填充报表3D数组之前执行的。
如何在getCompanyFolders()完全完成后启动showReportsHTML()函数?
答案 0 :(得分:1)
WL.api()
是异步的,因此继续执行下一个函数。
每个函数都可以返回延迟对象:
getCompanyFolders().done(function() {
showReportsHTML();
});
function getCompanyFolders() {
var getCompanyDeferred = $.Deferred();
WL.api({
path: "/me/skydrive/shared",
method: "GET"
}).then(function(response) {
var deferreds = []
foreach(item in response) {
deferreds.push(getReportFolders());
}
$.when.apply($, deferreds).done(function() {
getCompanyDeferred.resolve();
});
});
return getCompanyDeferred.promise();
}
这显然是一个简化的例子。 getReportFolders
和getReports
的结构看起来非常相似。如果您需要我进一步举例,请告诉我。
根据您的更新进行修改
还有几件事。首先,
getCompanyFolders();
应该是:
getCompanyFolders().done(function() {
showReportsHTML();
});
其次,$.when()
接受deferred
或promise
个对象,在您的情况下,这些对象是函数的返回值。
因此,在getCompanyFolders
中,调用getReportFolders
会返回您的延迟对象。这些结果应该被推入数组并传递给$.when
:
function getCompanyFolders() {
var getCompanyFoldersDeferred = $.Deferred();
WL.api({
path: "/me/skydrive/shared",
method: "GET"
}).then(
function(response) {
companyFolders = [];
reportFolders = [];
reports = [];
var deferreds = []; // <------- new array to hold deferred objects
for (var i = 0; i < response.data.length; i++) {
if (response.data[i].type == "folder") {
companyFolders.push(response.data[i]);
deferreds.push(getReportFolders(response.data[i].id + "/files/", companyFolders.length - 1)); // <------- hang on to the results from this function
}
}
$.when.apply($, deferreds).done(function() { // <--- wait on all the deferreds to resolve
getCompanyFoldersDeferred.resolve();
});
}, function(response) {
log("Cannot get files and folders: " + JSON.stringify(response.error).replace(/,/g, ",\n"));
});
return getCompanyFoldersDeferred.promise();
}
getReportsFolders
需要进行类似的更改。
getReports
无需等待其他任何事情来解决。一旦我们收到回调,我们就完成了:
function getReports(path, index1, index2) {
var getReportsDeferred = $.Deferred();
//var index3 = 0;
WL.api({
path: path,
method: "GET"
}).then(
function(response) {
reports[index1][index2] = [];
for (var i = 0; i < response.data.length; i++) {
if (response.data[i].type == "file") {
reports[index1][index2].push(response.data[i]);
//index3++;
}
}
getReportsDeferred.resolve(); // <---- all done, nothing else to wait on.
}, function(response) {
log("Cannot get files and folders: " + JSON.stringify(response.error).replace(/,/g, ",\n"));
});
return getReportsDeferred.promise();
}
答案 1 :(得分:0)
这是因为getCompanyFolders
正在调用异步函数。如果您希望在此功能完成后发生某些事情,则必须提供回调函数:
function getCompanyFolders(callback) {
companyFolders = [];
WL.api({
path: "/me/skydrive/shared",
method: "GET"
}).then(
function(response) {
reportFolders = [];
reports = [];
for (var i = 0; i < response.data.length; i++) {
if (response.data[i].type == "folder") {
companyFolders[companyFolders.length] = response.data[i];
getReportFolders(response.data[i].id + "/files/", companyFolders.length - 1);
}
}
callback();
}, function(response) {
log("Cannot get files and folders: " + JSON.stringify(response.error).replace(/,/g, ",\n"));
callback();
});
}
现在您可以致电getCompanyFolders
并简单地将showReportsHTML
作为参数传递。
getCompanyFolders(showReportsHTML);