JQuery - Can Threads / Asynchronous Operations Be Done?

I am currently using AJAX

with Django

Framework.

I can pass asynchronous

POST / GET to Django

and return an object to it json

.

Then, according to the output from Django

, I will loop through the data and update the table on the web page.

HTML for the table:

<!-- 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>

      

It is mostly modal bootstrap 3

, with jQuery DataTable

and with a progress bar to show the user the current progress.

The Javascript used to get Django results:

$('#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");
});

      

Problem with part of update table:

    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%");

      

Since the variable response.variables can be over 10k and this will freeze the web browser even though it is still drawing.

I'm new to web design (less than 4 months old), but I'm guessing they all work in the same thread.

Is there a way in Javascript for streaming / async processing? I had a search and the results were delayed / promised, which seems very abstract at the moment.

0


source to share


2 answers


Try to process the received data step by step.

In the snippet below, elements generated in 250 blocks, mostly using jQuery deferred.notify () and deferred.progress () .

When processing all 10,000 objects, an object deferred

resolved

with a collection of 10,000 items. The items are then appended to document

when called once .html()

in the deferred.then () .done()

callback; .fail()

callback cast as null

.

Alternatively, you can add items in document

blocks 250, within the deferred.progress

callback; instead of a single call inside deferred.done

that occurs after the entire task is completed.



setTimeout

is used to prevent "web browser freezing".

$(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>
      

Run codeHide result


jsfiddle http://jsfiddle.net/guest271314/ess28zLh/
+3


source


Deferring / promises won't help you. JS in the browser is always single-threaded.



The trick is not to create DOM elements via JS. It will always be expensive and slow. Instead of passing data to JSON from Django and dynamically generating the DOM, you should force Django to render the server-side template snippet and push the whole thing to the front where JS can just inject it at the appropriate point.

+1


source







All Articles