【问题标题】:Asynchronous execution of functions in javascriptjavascript中函数的异步执行
【发布时间】:2017-07-28 10:14:35
【问题描述】:

我想同时调用两个函数,比如函数a() 和函数b()。这些功能彼此独立,可以说执行这两个功能所需的时间不固定。有时函数a() 会比函数b() 花费更多时间,反之亦然。但是还有另一个函数 c() 应该只在函数 a()b() 都完成时才执行。

我应该如何使用 jQuery 的 Deferred 对象来做到这一点?

【问题讨论】:

标签: javascript jquery function jquery-deferred


【解决方案1】:

要实现这一点,您可以使a()b() 函数返回延迟对象,一旦它们的逻辑完成,您就可以resolve()。一旦前面的两个功能都完成,您就可以运行c()。试试这个:

function a() {
  var aDef = $.Deferred();
  setTimeout(function() {
    aDef.resolve('a done');
  }, 1000);
  return aDef;
}

function b() {
  var bDef = $.Deferred();
  setTimeout(function() {
    bDef.resolve('b done');
  }, 3000);
  return bDef;
}

function c() {
  console.log('all done!')
}

console.log('running...');
$.when(a(), b()).done(function(a, b) {
  console.log(a);
  console.log(b);
  c();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

【讨论】:

  • 无法与 193k 用户竞争...我回答得太慢了 :(
【解决方案2】:

我会使用一个全局变量来确定操作状态,并每 100 毫秒(或者如果需要,每毫秒)执行一次轮询。

var myStatus = {
  "a": false,
  "b": false
};

function a() {
  myStatus["a"] = true;
  console.log(myStatus['a']);
}

function b() {
  myStatus["b"] = true;
}

function getStatusText() {
  var s = 'not complete';
  if (myStatus.a && myStatus.b) {
    s = 'all complete';
  } else {
    if (myStatus.a) {
      s = 'a complete';
    }
    if (myStatus.b) {
      s = 'b complete';
    }
  }
  return s;
}

function c() {
  //check operational status
  var statusText = getStatusText();
  document.getElementById('status').innerHTML = statusText;
}
setInterval(
  function() {
    c()
  }, 100);
<button onclick="a()">Set a() complete</button><button onclick="b()">Set b() complete</button>

<p>operational status <span id="status"></span></p>

【讨论】:

    【解决方案3】:

    请参考jquery defer 和promise 方法来处理调用。

    https://api.jquery.com/deferred.promise/

    https://api.jquery.com/promise/

    【讨论】:

      【解决方案4】:

      这不完全是问题的答案。我不使用 defer 或类似的东西。

      但我想展示一些我经常做的事情:添加一个 onReady 回调,作为 a() 和 b() 的参数。我将这些回调添加到任何需要时间执行的自写函数中。

      function a(onready) {
        // let's say we get Ajax data
        $.ajax({
          url: 'data.php',
          success: function(data) {
            $('#message').html(data);
            if(typeof onready == 'function') {
              onready();   // you might also want to add message as a parameter, like onready(data), or anready('Data okay'), ...
            }
          }
        });
      }
      
      function b(onready) {
        // let's say we sort <table> rows
        sortTable('my_table', 'my_row', 'ASC');  // this function (not provided here) is not asynchronous, it just takes time before it's done
        if(typeof onready == 'function') {
          onready();   
        }
      }
      
      function c() {
        alert('Yippy!');
      }
      
      $(document).ready(function() {  // or this could be after the client clicks on a button, or so
        var aReady = false;
        var bReady = false;
      
        a(function() {
          aReady = true;
          if(aReady && bReady) {
            c();
          }
        });
      
        b(function() {
          bReady = true;
          if(aReady && bReady) {
            c();
          }
        });
      
      }); 
      

      【讨论】:

        【解决方案5】:

        您可以使用 jQuery.when() 来执行此操作。请在https://api.jquery.com/jquery.when/阅读有关此的文档

        a = function () {
        //your code for function a
        }
        b = function () {
        //your code for function b
        }
        
        $.when( a(), b() ).done(function c() {
            //your code for function c
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-12-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多