【问题标题】:JavaScript: Continue with function after another function call finishesJavaScript:在另一个函数调用完成后继续函数
【发布时间】:2011-08-31 17:34:19
【问题描述】:

编辑: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 调用。我可以修改回调,但这只是一个简单的测试集脚本,从控制台运行。有什么想法吗?

【问题讨论】:

  • 您的第一个选择器相当多。可以简化为:input:not([type="hidden"],:button).
  • 从代码和解释看问题不是很清楚。
  • 您应该包含纯 Javascript 或添加 jQuery 标签。大约 80% 的 Javascript 开发人员不会处理 jQuery 问题。但请记住,大约 90% 的互联网 cmet 统计数据都是即时生成的。
  • 嗯,一种提问方式是实际提出问题......很难说出您可能遇到什么问题,因为大多数代码似乎根本没有真正的目的。跨度>
  • @pimvdb:包括我不想要的按钮。我确实有一个错字(应该两次提交而不是按钮)。

标签: javascript jquery testing


【解决方案1】:

不太确定你的代码要做什么

但回答问题如何在另一个函数调用完成后继续使用函数:-

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

到下一个异步函数... asyncCall(callback1) { 回调1(回调2){ 回调2(...) } }

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 问题可能是each() 订购商品的方式。但是,如果它是按 DOM 顺序排列的,那应该不是问题。子选择的选项基于选择的值。因此,查看循环值在选择上发生更改,然后调用更改事件(调用 AJAX,填充子选择),each() 中的下一项应该是子选择,我想等待直到它被填充(有options)。
    【解决方案3】:

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

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

    如果您确实需要与 AJAX 调用相同的函数中的数据,则需要发出同步请求。但是,这会影响用户体验,因为整个浏览器在等待响应时会冻结。

    【讨论】:

    • 是的,我意识到关于 AJAX 位的同步性,但我真的不想搞砸生产代码,因为我只是想创建一个测试,自动填充动态填充元素。我不得不相信还有另一种方法,可能是扩展 onchange 功能。我认为您可以执行 setTimeout 并让其他操作继续进行,这就是为什么我最初将它放在 while 循环中的原因——我认为这不太好。调试时,我确实看到 AJAX 确实在 while 循环正在处理时返回。
    • @vol7ron:即使响应在您的循环运行时到达,处理响应的代码也无法运行。您可以使用超时来模拟 AJAX 调用的异步部分。超时回调代表AJAX调用成功回调:jsfiddle.net/Guffa/kdFFf
    • 感谢您的帮助,我在stackoverflow.com/questions/7262986/… 创建了一个新问题,因为我最初的问题可能让人们望而却步。我已投票结束此问题。
    猜你喜欢
    • 1970-01-01
    • 2018-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    相关资源
    最近更新 更多