web-dev-qa-db-ja.com

別の関数が完了した後に関数を実行する

function1 = function(){

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

}

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

function1();
function2();

だから私はjQueryの約束について聞いた。 「据え置き」オブジェクトを返し、イベントハンドラー内でdeferred.resolve();を呼び出します。

しかし、複数のイベントハンドラーがあり、すべてが起動されたときに次の関数のみを実行したい場合はどうなりますか? +コードの他の部分に「据え置き」のような異質なものを導入するという考えは好きではありません。

Function1がすべての作業を完了したかどうかを検出する他の方法はありますか?

5
thelolcat

これを試して、

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

    fuction2;

});

ここで、fuction1は最初に呼び出す関数で、fuction2は2番目の関数です。

12
Jinesh

Promiseアプローチを採用するか、callbackアプローチを採用します。

コールバックでは、_function2_をパラメーターとして_function1_に渡します。

_function1 = function(callback){

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

}

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

function1(function2);
_

...しかし、_function3_が_function2_に依存し、_function4_が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);
_

multiple据え置きを組み合わせるreal方法は $.when() ですが、残念ながらここには複数の遅延オブジェクトがなく、それらを追加するのはmaybeFireアプローチを使用するのと同じくらい面倒です。

5
Matt

transitionendallcssプロパティ値内に設定されている場合、transitionイベントが複数回発生する可能性があることに注意してください。

(このパターン)を試す

例:

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/

1
guest271314