简体   繁体   中英

JavaScript: Continue with function after another function call finishes

Edits: http://jsfiddle.net/vol7ron/wQZdM/

The fiddle should be used to help illustrate what I'm trying to do and what's happening. The sub-selects should be populated with the second option value.


Original Question:

Not sure the best way to ask. I'm creating a testing script to autofill inputs on a form.

It includes a series of drop-down select boxes, which populate other select options in an onChange event. When trying to auto-populate the form, the sub-selects don't have any options.

console.clear();

// non-select inputs
$(':input:not([type="hidden"],[type="button"])').each(function(){
   $(this).val($(this).attr('name'))          // test value is simple input's name
});

// select inputs
var count=0, cutoff=7500;
$('select').each(function(){
   var t = $(this);
   var c = t.children('option');

   while( c.length <= 1 && count < cutoff){
      count++;
      c = $(this).children('option');       // tried not using the cache'd variable
      if (!(count % 10))
         console.log(count, c.length, "No Options");  // debugging -- never exists early

      setTimeout(function(){},0);           // not really doing anything
   }

   t.val( c.eq(1).val() );                  // set value to second option value
   t.trigger('change');                     // calls the onChange even if it doesnt exist
});

// verify it does have data
console.log($('#sub-select').children('option').length); // does have options

There's an AJAX call in the change event. I could modify the callback, but this is just a simple set script for testing, that is run from console. Any ideas?

Not really sure what your code is trying to do

But answering the question How to continue with function after another function call finishes :-

assuming you have a list of functions which are all asynchronous you can nest them to continue

to the next asynchronous function ... asyncCall(callback1) { callback1(callback2) { callback2(...) } }

Checkout https://github.com/caolan/async for some elegant ways to do this

this example calls all functions in order even though they are asynchronous.

async.series([
        function(callback){
            setTimeout(function(){
                call_order.push(1);
                callback(null, 1);
            }, 25);
        },
        function(callback){
            setTimeout(function(){
                call_order.push(2);
                callback(null, 2);
            }, 50);
        },
        function(callback){
            setTimeout(function(){
                call_order.push(3);
                callback(null, 3,3);
            }, 15);
        }

1) Use Synchronous AJAX request http://api.jquery.com/jQuery.ajax/

var html = $.ajax({
  url: "some.php",
  async: false
 }).responseText;

2) Instead of using the .each use .eq(index) and just call it in order.

function FakeEach(idx) {
    if(idx >= 7500) return;
    var $obj = $('select').eq(idx);
    if($obj.length == 0) return;
    ...
    $obj.trigger('change');
    window.setTimeout(function() { FakeEach(idx++); }, 0);
}

Your problem is that you are starting an AJAX request in the function, and expect that the response arrives before the function ends. As long as you are using an asynchronous request, this will never happen. You have to exit your function before the code that handles the response can run. Javascript is single threaded, so as long as your function is running, no other code can run.

The solution to the problem is to put the code that uses the data in the success callback function that is called after the response has arrived. Eventhough you usually write that function inside the function that makes the AJAX call, it's a separate function that will run later.

If you really need the data in the same function as the AJAX call, you would need to make a synchronous request. This is a killer for the user experience, though, as the entire browser freezes while it is waiting for the response.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM