0

我正在用 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() 函数?

4

2 回答 2

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()接受deferredpromise对象,在您的情况下是函数的返回值。

因此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();
}
于 2013-07-09T17:51:30.310 回答
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);
于 2013-07-09T17:48:20.653 回答