2013-07-09 141 views
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(); 

shoulde執行getCompanyFolders後發揮了一個又一個()函數完成其工作。但是在getCompanyFolders()填充報表3D數組之前執行showReportsHTML()。

如何在getCompanyFolders()完成後啓動showReportsHTML()函數?

+0

異步調用,愛上它們。 – epascarello

回答

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

這顯然是一個簡化的例子。 getReportFoldersgetReports的結構看起來非常相似。讓我知道你是否需要我進一步採取這個例子。

編輯迴應您的更新

一對夫婦的事情還。首先,

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(); 
} 
+0

好吧,getCompanyfolders()也調用getReportFolders(),這個函數調用getReports()。在所有這些序列之後,我需要調用showReportsHtml()來遍歷所有的報告[] [] []數組成員並添加一些DOM元素和文本。所以我不認爲2或3方法會起作用。另外,我還沒有找到WL.api返回有希望的對象的信息。 如果我不能這樣做, 然後我要在getCompanyFolder(),getReportFolders()和getReports()函數中添加DOM元素。你認爲這將是一個好主意嗎? – Rokas

+0

@Rokas編輯,以顯示我認爲是一個更好的解決方案..沒有想到它的第一次。 –

+0

哦,我記得我不能這樣做「如果我不能這樣做,那麼我會在getCompanyFolder(),getReportFolders()和getReports()函數中添加DOM元素。」 我需要知道,當getCompanyFolders,getReportFolders,getReports的序列將完成,然後調用showReportsHTML函數.. – Rokas

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); 
相關問題