2017-06-02 57 views
0

我已经尝试了许多不同的方法来执行此操作。
像下面的代码一样,我试图在.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完成之前正在运行。

我们还能做什么?

回答

0

我发现从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

+0

如何传递folderURL的列表 – KumarV

0

你是做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. 
     } 

     }); 

    } 
+0

这里还有一个问题,因为第二个'getJSON'请求可能比第一个'getJSON'请求更快地发送答案。我认为如果你想这样做,你必须做一个同步ajax调用,这不是很好 – UfguFugullu

+0

不,这将工作正常,因为我递增计数器变量,它只会等于'ohrArray'的长度只有当所有的请求都成功返回.. – void

+0

对不起,我的脑海里溢出了。你是对的 - 这会起作用 – UfguFugullu

2

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


} 

我可能没有格式化或放错某些括号,因为我没有运行代码。

+0

你为什么要编写'iterate.resolve();'完成ajax调用的功能。在少数情况下,代码执行可能无法到达那里。不能在每个循环完成之前完成。 – KumarV

+0

我的错,我以为你想让代码在ajax完成时运行。我将编辑我的答案,但在此之前,让我澄清一下:你是否希望代码在'.each'中的所有迭代已经完成或在'.each()'语句之后运行。我在问,因为'.each'中的函数是异步调用的,'.each()'后面的语句是在迭代完成前立即调用的。 – vassiliskrikonis

+0

我希望代码在.each循环完成后运行 – KumarV

相关问题