【问题标题】:Run function after another one completes在另一个完成后运行函数
【发布时间】:2014-09-28 10:20:29
【问题描述】:
function1 = function(){

  something.on('transitionend', function(){
    // now function2 should run
  });

}

function2 = function(){
  alert('ok');
}

function1();
function2();

所以我听说了 jQuery 承诺。我会返回一个“延迟”对象,并在事件处理程序中调用 deferred.resolve();

但是如果我在那里有多个事件处理程序并且我只希望下一个函数在所有事件都被触发后运行会发生什么? + 我不喜欢在代码的其他部分引入诸如“延迟”之类的外来内容。

有没有其他方法可以检测 function1 是否完成了所有工作?

【问题讨论】:

  • function2 作为参数传递给function1,并在回调中调用.on。如:function1(function2); 然后:function1 = function(callback){ something.on('transitionend', callback); }

标签: javascript jquery jquery-plugins jquery-deferred jquery-events


【解决方案1】:

试试这个,

 $.when($.ajax(fuction1())).then(function () {

    fuction2;

});

这里 fuction1 是您要调用的第一个函数,而 fuction2 是您要调用的第二个函数。

【讨论】:

  • 为了它的价值,我尝试使用它,它导致我的页面重新加载..在我的情况下,这意味着对 geolocator api 的 3 次调用
【解决方案2】:

要么采用 promise 方法,要么采用回调方法。

使用回调,您可以将function2 作为参数传递给function1

function1 = function(callback){

  something.on('transitionend', function(){
      callback();
  });

}

function2 = function(){
  alert('ok');
}

function1(function2);

...但是如果你有 function3 依赖于 function2function4 依赖于 3,那么你就会陷入嵌套地狱。

这就是为什么你要走延迟路线;

function1 = function(){
  var def = new jQuery.Deferred();

  something.on('transitionend', function(){
      def.resolve(arguments);
  });

  return def.promise();
}

function2 = function(){
  alert('ok');
}

function1().done(function2);

... 这将允许您链接连续的函数而不是嵌套它们(当然,前提是它们都返回了 Promise)。

将事件处理程序和延迟事件结合起来有点混乱。因此,如果您沿着拥有多个事件处理程序的路线走下去,您最终将不得不做一些蹩脚的事情,例如;

function1 = function(){
  var def = new jQuery.Deferred();
  var wait = 4;

  function maybeFire() {
      if (--wait) {
          def.resolve();
      }
  }

  something.on('transitionend', maybeFire);
  something.on('somethingelse', maybeFire);
  something.on('somethingelse', maybeFire);
  something.on('somethingelse', maybeFire);

  return def.promise();
}

function2 = function(){
  alert('ok');
}

function1().done(function2);

真正的组合多个延迟的方式是使用$.when(),但不幸的是这里你没有多个延迟,添加它们会像使用maybeFire 方法。

【讨论】:

    【解决方案3】:

    注意,如果all 设置在css transition 属性值内,transitionend 事件可能会触发多次

    试试(这个模式)

    例如,

    html

    <button>click</button>
    

    css

    button {
        width: 100px;
        -webkit-transition: width 1s;
    }
    .transition {
        width: 150px
    }
    

    js

    $(function() {
        // `$.Callbacks("once")` to fire `alert` once ,
        // even if `all` set within `css` `transition` 
        // property value
        var callbacks = $.Callbacks(); 
    
        function2 = function(j) {
          alert(j);
        };
    
        callbacks.add(function2);
    
        $(window).on("transitionComplete", function(e, i) {
         // function2(i);
            callbacks.fireWith($(this), [i]);
        });
        // `webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd`
        function1 = function() {
          $("button").on('transitionend', function (e) {
            $(window).trigger("transitionComplete", ["ok"]);
          });
        };
    
        function1();
    
        $("button").on("click", function(e) {
          $(this).toggleClass("transition");
        });
    
    });
    

    jsfiddle http://jsfiddle.net/guest271314/u7B9K/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      • 2013-11-09
      相关资源
      最近更新 更多