完成每个循环后的代码
我已经尝试了许多不同的方法来执行此操作。
像下面的代码一样,我试图在.each
迭代完成后运行代码。完成每个循环后的代码
function test(){
var iterate = $.each(ohrArray, function(i, val){
var ohrID = ohrArray[i];
var folderUrl = 'EFMSEmployeeDocumentList' + "/" + locationFolder;
var url = _spPageContextInfo.webServerRelativeUrl + "/_api/Web/GetFolderByServerRelativeUrl('" + folderUrl + "')?$expand=Files";
$.getJSON(url,function(data,status,xhr){
for(var i = 0; i < data.Files.length;i++){
modifiedDate= new Date(data.Files[i].TimeLastModified);
if(documentTitle == ""){
showData(ohrID ,data.Files[i].Title,data.Files[i].ServerRelativeUrl,modifiedDate);
countItems++;
}else{
if(documentTitle == data.Files[i].Title)
countItems++;
showData(ohrID ,data.Files[i].Title,data.Files[i].ServerRelativeUrl,modifiedDate);
}
}
}
}).complete(function(){
$('#tblCustomListData').dataTable({
paging: true,
searching: true,
bDestroy: true,
"iDisplayLength": 5,
"lengthMenu": [5,10, 25, 50, 100]
});
if(countItems == 0){
alert("No Files Exists");
$("#divCustomListData").hide();
}
});
}
});
$.when(iterate)
.then(function(iterate){
if(countItems == 0){
alert("No Files Exists");
}
});
}
仍在调试时发现代码.then
在.each完成之前正在运行。
我们还能做什么?
我发现从dataTable的here
$(document).ready(function() {
$('#example').DataTable({
"ajax": "data/objects.txt",
"columns": [
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "extn" },
{ "data": "start_date" },
{ "data": "salary" }
]
});
});
的解决方案,否则我想你应该改变你的API,所以你可以给API的folderURL
的List。
然后,您不需要在.each()
的每个循环中发送请求。
而且你应该能够在success
回调一个来创建dataTable
只有getJSON
你是做XMLHTTPRequeat的$.each
里面,所以我想你想的时候所有的请求进行处理,以执行一些代码。这不会直接发生,因为JS本质上是异步的。
您可以保留一些计数器变量来跟踪处理的总请求。事情是这样的:
var iterate = $.each(ohrArray, function(i, val) {
var url = "......";
var counter = 0;
$.getJSON(url, function(data, status, xhr) {
counter++;
/**** Rest of the code ****/
if (counter == ohrArray.length) {
// Execute the required code by pasting it here or calling a function.
}
});
}
这里还有一个问题,因为第二个'getJSON'请求可能比第一个'getJSON'请求更快地发送答案。我认为如果你想这样做,你必须做一个同步ajax调用,这不是很好 – UfguFugullu
不,这将工作正常,因为我递增计数器变量,它只会等于'ohrArray'的长度只有当所有的请求都成功返回.. – void
对不起,我的脑海里溢出了。你是对的 - 这会起作用 – UfguFugullu
iterate
应该是一个承诺。
当你通过$.when()
的东西,这不是一个承诺它默认为一个已解决的,所以$.then()
立即执行。
若要使用承诺在jQuery的检查$.Deferred
话又说回来,你检查countItems
当每个Ajax调用响应它获取才会更新。所以你真正需要的是完全抛弃.complete()
并且有Promise的数组。在.each
中的每次迭代都会在数组中创建一个新的Promise,然后我们将使用$.when()
来检查何时所有 Promise都已解决。
function test(){
var promises = []; //
$.each(ohrArray, function(i, val){
var d = $.Deferred(); // keep the reference to the promise
promises.push(d); // push the promise into the array
var ohrID = ohrArray[i];
var folderUrl = 'EFMSEmployeeDocumentList' + "/" + locationFolder;
var url = _spPageContextInfo.webServerRelativeUrl + "/_api/Web/GetFolderByServerRelativeUrl('" + folderUrl + "')?$expand=Files";
$.getJSON(url,function(data,status,xhr){
for(var i = 0; i < data.Files.length;i++){
modifiedDate= new Date(data.Files[i].TimeLastModified);
if(documentTitle == ""){
showData(ohrID ,data.Files[i].Title,data.Files[i].ServerRelativeUrl,modifiedDate);
countItems++;
}else{
if(documentTitle == data.Files[i].Title)
countItems++;
showData(ohrID ,data.Files[i].Title,data.Files[i].ServerRelativeUrl,modifiedDate);
}
} // end of for loop
d.resolve(); // the ajax in this iteration has been resolved
}
});
// $.when doesn't accept array of promises by default
$.when.apply(this, promises).then(function(){
// now all the promises have been resolved
// code inside the .complete you had in your question
$('#tblCustomListData').dataTable({
paging: true,
searching: true,
bDestroy: true,
"iDisplayLength": 5,
"lengthMenu": [5,10, 25, 50, 100]
});
if(countItems == 0){
alert("No Files Exists");
$("#divCustomListData").hide();
}
iterate.resolve();
});
}
});
}
我可能没有格式化或放错某些括号,因为我没有运行代码。
你为什么要编写'iterate.resolve();'完成ajax调用的功能。在少数情况下,代码执行可能无法到达那里。不能在每个循环完成之前完成。 – KumarV
我的错,我以为你想让代码在ajax完成时运行。我将编辑我的答案,但在此之前,让我澄清一下:你是否希望代码在'.each'中的所有迭代已经完成或在'.each()'语句之后运行。我在问,因为'.each'中的函数是异步调用的,'.each()'后面的语句是在迭代完成前立即调用的。 – vassiliskrikonis
我希望代码在.each循环完成后运行 – KumarV
如何传递folderURL的列表 – KumarV