2

これと同様の機能を取得したいと思います:

function foo(before, after){

    before();

    setTimeout(function(){
         after();
    },100)
}

foo(function(){
    console.log('before');
}, function(){
    console.log('after');
});

コールバックを使用する代わりにオブジェクトを返す場合 (疑似コード):

var foo = function() {

     before();         

     setTimeout(function(){
         after();
     },100)

     return {
         before: before,
         after: after
     }
};

foo().before(function(){
    console.log('before');
});

foo().after(function(){
    console.log('after');
});

またはおそらく

foo().before(function(){
    console.log('before');
}).after(function(){
    console.log('after');
});

これは可能ですか?

4

5 に答える 5

4

はい、関数は、どのコールバックが設定されているかを追跡するbeforeおよびメソッドを使用してオブジェクトを返すことができます。両方が設定されている場合は、それらを呼び出すことができます。after

function foo() {

    var beforeFunc = null, afterFunc = null;

    function activate() {
        beforeFunc();
        window.setTimeout(afterFunc, 100);
    }

    var obj = {
        before: function(f) {
            beforeFunc = f;
            if (afterFunc != null) activate();
            return obj;
        },
        after: function(f) {
            afterFunc = f;
            if (beforeFunc != null) activate();
            return obj;
        }
    };

    return obj;

}

// As both callbacks need to be set, the order is not important
foo().after(function(){
    console.log('After');
}).before(function(){
    console.log('Before');
});

デモ: http://jsfiddle.net/4HypB/

于 2013-08-31T23:18:55.680 に答える
2

それはほとんど可能です。

ただし、提案された使用例の問題は、コールバックまたはコールバックが指定さfoo()れる前に呼び出されることです。一方、実装例では、これらのコールバックは 内で実行されます。したがって、それは達成できません。メソッドが既に実行された後、そのメソッドで発生したことをさかのぼって変更することはできません。beforeafterfoo

経由で提供されたコールバックをすぐfooに実行することが本当に必要な場合 (つまり、純粋な同期実行が必須でない場合) は、単純な呼び出しで目的を達成できます。setTimeout

function foo() {
  var callbacks = {
    before: function() {},
    after: function() {}
  };

  setTimeout(function() {
    callbacks.before();
    setTimeout(callbacks.after, 100);
  }, 0);

  return {
    before: function(callback) {
      callbacks.before = callback;
      return this;
    },

    after: function(callback) {
      callbacks.after = callback;
    }
  };
}

ここで、は、 のメソッド本体内で閉じられfoo()たオブジェクトを変更するメソッドを公開するオブジェクトを返します。これらのメソッドは、実行後、イベント ループの次のティックで使用されます。callbacksfoo foo()

このコードの動作を確認したい場合は、JSBin で例を作成しました。

于 2013-08-31T23:15:29.043 に答える
1

Phrogzの答えは良いですが、FWIWプロトタイプなしでこれを行うこともできます:

function foo() {
  ret = function () { return ret.call(); };
  ret.call = function () {
    this._before();
    setTimeout(this._after,100);
  };
  ret.before = function (x) { this._before = x; return this; };
  ret.after = function (x) { this._after = x; return this; };
  return ret;
};

test = foo().before(function(){
  console.log('before');
}).after(function(){
  console.log('after');
});

呼び出し:

test();

あなたが期待することをします。

于 2013-08-31T23:20:29.973 に答える
1
function foo(){};
foo.prototype.before = function(f){ this._before = f };
foo.prototype.after  = function(f){ this._after  = f };
foo.prototype.go = function(){
  this._before();
  setTimeout(this._after,100);
}

var f = new foo;
f.before(function(){ … });
f.after(function(){ … });
f.go();

しかし、繰り返しますが、これをもっと簡単にすることもできます:

function foo(){};
foo.prototype.go = function(){
  this.before();
  setTimeout(this.after,100);
}

var f = new foo;
f.before = function(){ … };
f.after  = function(){ … };
f.go();
于 2013-08-31T23:15:50.193 に答える
1

別のバリエーションを次に示します。

var createFooBuilder = function () {
    var before = function() {};
    var after = function() {};

    var func = function () {
        before();
        setTimeout(function () {
            after();
        }, 100)
    };

    func.before = function(value) {
        before = value;
        return func;
    }
    func.after = function(value) {
        after = value;
        return func;
    }

    return func;
};

var foo = createFooBuilder();

foo.before(function () {
    console.log('before');
}).after(function () {
    console.log('after');
});

foo();

jQuery Deferredを機能させることをお勧めします。そうすれば、アフター関数のリストを作成できます。

于 2013-08-31T23:18:24.677 に答える