【问题标题】:How to Execute code after function is complete函数完成后如何执行代码
【发布时间】:2019-06-18 22:02:26
【问题描述】:

我有一个代码,基本上我创建了一个函数,在 jQuery ajax 的帮助下,我获取一个值并将其设置为元素的数据属性。

然后在调用函数后,我将数据值存储在一个变量中。

但问题是我不想在 ajax 函数完成之前执行任何代码。

JS

function load_data(){
    $.ajax({
       .....,
       success: function (response) {
           $('.element').attr('data-foo', 'bar')
       }
    })
}
load_data(); //let the function set data first
console.log($('.element').data('foo')) //then execute this line

如何做到这一点?

【问题讨论】:

  • 将该行代码放入“成功”回调中。这就是回调的用途
  • @Pointy 是的,我也考虑过这一点,但我正在寻找其他选择。也许通过使用 async-await

标签: javascript jquery ajax async-await


【解决方案1】:

您可以在load_data 中接收回调函数并在success 函数中执行它。像这样的:

function load_data(callback){
    $.ajax({
       .....,
       success: function (response) {
           $('.element').attr('data-foo', 'bar');
           callback();
       }
    })
}

load_data(function() {
  console.log($('.element').data('foo'));
});

当然,如果这是您的真实场景,您可以简单地将console.log($('.element').data('foo')); 直接放在success 函数中。

【讨论】:

    【解决方案2】:

    您可以使用 Async-Awaithttps://javascript.info/async-await

    async function load_data(){
        await $.ajax({
           .....,
           success: function (response) {
               $('.element').attr('data-foo', 'bar')
           }
        });
        console.log($('.element').data('foo')) //then execute this line
    }
    load_data(); //let the function set data first
    
    

    另外,你也可以使用回调来做到这一点。

    function load_data(callback){
        $.ajax({
           .....,
           success: function (response) {
               $('.element').attr('data-foo', 'bar');
               callback();
           }
        })
    }
    
    function doItLater(){
        console.log($('.element').data('foo')) //then execute this line
    }
    
    load_data(doItLater); //let the function set data first
    

    您可以将数据作为参数传递给 doItLater 以获取当前范围内的数据。

    【讨论】:

    • $.ajax 不返回承诺 afaik,因此 await 会抛出错误。
    • @Jaxi 是的,它确实返回了一个 Promise
    • @Pointy 啊,够公平的!
    【解决方案3】:

    尝试使用 .done()

    load_data()
       .done(function(dataResponse){
               console.log($('.element').data('foo')) //then execute this line
       }); //let the function set data first
    

    内部代码将在您的 ajax 调用得到响应并且dataResponse 收到您的 ajax 调用的任何响应后运行

    【讨论】:

      【解决方案4】:

      由于异步 ajax 调用,这不可能直接实现。

      有两种方法可以实现你想要的

      1.

      • 为你想要在成功的 ajax 请求后执行的代码创建一个函数

      • 从 ajax 成功块调用该函数

      例如。

      function load_data(){
          $.ajax({
             .....,
             success: function (response) {
                 $('.element').attr('data-foo', 'bar');
                 console.log($('.element').data('foo')); // Your code goes here
             }
          })
      }
      

      2

      • load_data函数中返回$.ajax
      • 并对 load_data 本身使用 .then.done 函数

      例如。

      function load_data(){
          return $.ajax({
             .....,
                 success: function (response) {
                     $('.element').attr('data-foo', 'bar')
                 }
              })
      }
      
      load_data().done(function() {
        console.log($('.element').data('foo')); // Your code goes here
      });
      

      但是,.done 和 .then 的行为不同。特别是,如果一个标准的 Promise 回调返回另一个 Promise,这将延迟所有后续 Promise 的解析。 jQuery 的行为是这样的,但 done 不是。 done 回调不可能延迟后续回调的解析。

      【讨论】:

        【解决方案5】:

        Ajax 是异步的。所以,你必须倾听成功事件并做你的事情。您可以通过使用 await/async 来实现与您的需求类似的事情

        https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/async_function

        const load_data = async () => {
            return await fetch('https://exmaple.com');
        }
        
        load_data();
        
        $('.element').attr('data-foo', 'bar')
        

        【讨论】:

          【解决方案6】:

          您可以在设置元素属性后将控制台日志放在成功回调中。

          如果您不希望将控制台日志写入 load_data 中(也许您想让 load_data 可重用,而不需要控制台日志),您可以将控制台日志放入回调函数并将回调传递给 load_data 并调用它ajax成功函数:

          function load_data(cb){
              $.ajax({
                 .....,
                 success: function (response) {
                     $('.element').attr('data-foo', 'bar')
                     cb();
                 }
              })
          }
          
          function callback() {
            console.log($('.element').data('foo'))
          }
          
          load_data(callback);

          另一种选择是在 ajax 设置对象中设置 async: false,这将阻止在 ajax 函数解析之前执行以下代码,但这通常不是推荐的做法。

          【讨论】:

            猜你喜欢
            • 2022-11-01
            • 2013-08-21
            • 2018-01-12
            • 2012-02-08
            • 2014-10-27
            • 2022-01-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多