2013-07-09 101 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); 
相关问题