jQuery的 – 可以线程/asynchronous完成?

我目前正在与Django框架使用AJAX

我可以通过asynchronous POST / GET到Django ,并让它返回一个json对象。

然后根据从Django传递的结果,我将遍历数据,并更新网页上的表格。

表格的HTML:

 <!-- Modal for Variable Search--> <div class="modal fade" id="variableSearch" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button> <h4 class="modal-title" id="myModalLabel">Variable Name Search</h4> </div> <div class="modal-body"> <table id="variableSearchTable" class="display" cellspacing="0" width="100%"> <thead> <tr> <th> Variable Name </th> </tr> </thead> </table> <p> <div class="progress"> <div class="progress-bar progress-bar-striped active" id="variableSearchProgressBar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 45%"> <span class="sr-only">0% Complete</span> </div> </div> </p> <p> <div class="row"> <div class="col-lg-10"> <button class="btn btn-default" type="button" id="addSearchVariable" >Add</button> </div> </div> </p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" id="variableSearchDataCloseButton" data-dismiss="modal">Close</button> </div> </div> </div> </div> 

基本上它是一个bootstrap 3模式,与jQuery DataTable ,并与进度条向用户显示当前进度。

用来获取Django的Javascript结果:

 $('#chartSearchVariable').click(function(event) { $('#chartConfigModal').modal("hide"); $('#variableSearch').modal("show"); var csrftoken = getCookie('csrftoken'); var blockname = document.getElementById('chartConfigModalBlockname').value; $('#variableSearchProgressBar').css('width', "0%").attr('aria-valuenow', "0%"); event.preventDefault(); $.ajax( { type:"GET", url:"ajax_retreiveVariableNames/", timeout: 4000000, data: { 'csrfmiddlewaretoken':csrftoken, 'blockname':blockname }, success: function(response) { if(response.status == "invalid") { $('#chartConfigModal').modal("hide"); $('#variableSearch').modal("hide"); $('#invalid').modal("show"); } else { configurationVariableChart.row('').remove().draw(false); for (i = 0 ; i < response.variables.length; i++) { configurationVariableChart.row.add( $( '<tr>' + '<td>' + response.variables[i] + '</td>' + '<tr>' )[0]); } configurationVariableChart.draw(); $('#variableSearchProgressBar').css('width', "100%").attr('aria-valuenow', "100%"); } }, failure: function(response) { $('#chartConfigModal').modal("hide"); $('#variableSearch').modal("hide"); $('#invalid').modal("show"); } }); return false; }); $('#addSearchVariable').click(function(event) { $('#variableSearch').modal("hide"); $('#chartConfigModal').modal("show"); document.getElementById('chartConfigModalVariable').value = currentVariableNameSelects; }); $('#variableSearchDataCloseButton').click(function(event) { $('#variableSearch').modal("hide"); $('#chartConfigModal').modal("show"); }); 

问题是更新表部分:

  configurationVariableChart.row('').remove().draw(false); for (i = 0 ; i < response.variables.length; i++) { configurationVariableChart.row.add( $( '<tr>' + '<td>' + response.variables[i] + '</td>' + '<tr>' )[0]); } configurationVariableChart.draw(); $('#variableSearchProgressBar').css('width', "100%").attr('aria-valuenow', "100%"); 

由于response.variables可能超过10k,并且会冻结Web浏览器,即使它仍在绘制。

我对网页devise很陌生(less于4个月),但我认为这是因为它们都在同一个线程上运行。

有没有在Javascript的方式做线程/asynchronous? 我进行了一次search,结果是延迟/许诺,目前看来非常抽象。

尝试逐步处理检索到的数据。

在下面的片断中,使用jQuery deferred.notify()和deferred.progress()主要利用250个块生成的元素。

当所有10,000个项目被处理时, deferred对象被resolved具有10,000个元素的集合。 然后将元素添加到document ,在deferred.then()的.done()callback中调用.html().fail()callback.fail()null

或者,可以在deferred.progresscallback中以250个块为单位附加元素。 而不是在完成整个任务时发生的deferred.done中的单个调用。

setTimeout来防止“冻结Web浏览器”的情况。

 $(function() { // 10k items var arr = $.map(new Array(10000), function(v, k) { return v === undefined ? k : null }); var len = arr.length; var dfd = new $.Deferred(); // collection of items processed at `for` loop in blocks of 250 var fragment = []; var redraw = function() { for (i = 0 ; i < 250; i++) { // configurationVariableChart.row.add( // $( fragment.push('<tr>' + '<td>' + arr[i] + '</td>' + '</tr>') // )[0]); }; arr.splice(0, 250); console.log(fragment, arr, arr.length); return dfd.notify([arr, fragment]) }; $.when(redraw()) // `done` callbacks .then(function(data) { $("#results").html(data.join(",")); delete fragment; } // `fail` callbacks , null // `progress` callbacks , function(data) { // log , display `progress` of tasks console.log(data); $("progress").val(data[1].length); $("output:first").text(Math.floor(data[1].length / 100) + "%"); $("output:last").text(data[1].length +" of "+ len + " items processed"); $("#results").html("processing data..."); if (data[0].length) { var s = setTimeout(function() { redraw() }, 100) } else { clearTimeout(s); dfd.resolve(data[1]); } }) }) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <progress min="0" max="10000"></progress><output for="progress"></output> <output for="progress"></output><br /> <table id="results"></table> 

延期/承诺在这里不会帮助你。 浏览器中的JS总是单线程的。

诀窍是不通过JSbuild立DOM元素。 这总是会很昂贵和缓慢。 而不是从Django的JSON中传递数据并dynamic地构build一个DOM,你应该让Django在服务器端渲染一个模板片段,并将整个东西传递给前端,JS可以简单地将它插入到相关点。