JavaScript:在另一个函数调用完成后继续执行函数

时间:2011-08-31 17:34:19

标签: javascript jquery testing

编辑:http://jsfiddle.net/vol7ron/wQZdM/

小提琴应该用于帮助说明我正在尝试做什么以及发生了什么。应使用第二个选项值填充子选择。


原始问题:

不确定最好的方式。我正在创建一个测试脚本来自动填充表单上的输入。

它包含一系列下拉select框,用于填充onChange事件中的其他select选项。尝试自动填充表单时,子选择没有任何选项。

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

更改事件中有一个AJAX调用。我可以修改回调,但这只是一个简单的测试集脚本,它是从控制台运行的。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

不确定您的代码尝试做什么

但回答了如何在另一个函数调用结束后继续使用函数的问题: -

假设您有一个全部异步的函数列表,您可以将它们嵌套以继续

到下一个异步函数......     asyncCall(callback1){       callback1(callback2){         callback2(...)       }     }

结帐https://github.com/caolan/async了解一些优雅的方法

此示例按顺序调用所有函数,即使它们是异步的。

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 :(得分:1)

1)使用同步AJAX请求http://api.jquery.com/jQuery.ajax/

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

2)而不是使用.each使用.eq(index),只是按顺序调用它。

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

答案 2 :(得分:1)

您的问题是您正在函数中启动AJAX请求,并期望响应在函数结束之前到达。只要您使用异步请求,就不会发生这种情况。在处理响应的代码可以运行之前,您必须退出函数。 Javascript是单线程的,因此只要您的函数正在运行,就无法运行其他代码。

问题的解决方案是将使用数据的代码放在响应到达后调用的成功回调函数中。尽管你经常在进行AJAX调用的函数中编写该函数,但它是一个单独的函数,可以在以后运行。

如果您确实需要与AJAX调用相同功能的数据,则需要进行同步请求。然而,这是用户体验的杀手,因为整个浏览器在等待响应时冻结。