Run function after another one completes

2019-01-23 20:41发布

function1 = function(){

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

}

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

function1();
function2();

So I heard about jQuery promises. I would return a "deferred" object, and inside the event handler I would call deferred.resolve();

But what happens if i have multiple event handlers there and I only want the next function to run when all have been fired? + I don't like the idea of introducing something foreign like "deferred" into other parts of the code.

Is there any other way to detect if function1 has finished all its work?

3条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-01-23 21:00

Try this,

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

    fuction2;

});

Here fuction1 is your first function to call, and fuction2 is your second function.

查看更多
手持菜刀,她持情操
3楼-- · 2019-01-23 21:06

Note, transitionend event may fire multiple times if all is set within css transition property value

Try (this pattern)

i.e.g.,

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/

查看更多
趁早两清
4楼-- · 2019-01-23 21:07

Either you take the promise approach, or you take the callback approach.

With callbacks, you'd pass function2 as a parameter to function1;

function1 = function(callback){

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

}

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

function1(function2);

... but then you get nested-hell if you have function3 dependant on function2, and function4 dependant on 3.

This is why you'd go down the deferred route;

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

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

  return def.promise();
}

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

function1().done(function2);

... which would allow you to chain successive functions rather than nesting them (providing they all returned promises, of course).

Combining event handlers and deferreds is a bit messy. So if you went down the route of having multiple event handlers, you'd end up having to do something lame such as;

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

The real way of combining multiple deferreds is by using $.when(), but unfortunately here you don't have multiple deferreds, and adding them will be as messy as using the maybeFire approach.

查看更多
登录 后发表回答