2013-04-18 6 views
7

「非アヤックス」関数でjquery done()を使用できますか?私がこのようなことをしようとするとエラーUncaught TypeError: Cannot call method 'done' of undefinedが出ます。「非アヤックス」関数でjqueryを使用する

function countThreeSeconds() { 
    var counter = 0, 
    timer = setInterval(function() { 

     if (counter == 3) { 
      console.log("All done. That was three seconds."); 
      window.clearInterval(timer); 

     } else { 
      console.log("Not there yet. Counter at: " + counter); 
     } 
     counter++; 
    }, 1000); 

} 

(function(){ 
    var timer = countThreeSeconds().done(function(){ 
    alert("done"); 
    }); 

}()); 

おかげ

JSBIN

+3

あなたが見ることができるように、あなたがすることはできません。 jQueryはそれとは関係ありません。 'undefined'メソッドを決して呼び出すことはできません。 jQueryメソッドはどこにでも魔法のように表示されるだけではありません。 jQueryのライブラリで定義された特定のオブジェクトで、jQueryのAPIで説明されているように、それらを呼び出すことができます。 –

答えて

13

は非アヤックス機能が約束オブジェクトを返すことを確認します。

function countThreeSeconds() { 
    var counter = 0, 
    deferred = $.Deferred(), 
    timer = setInterval(function() { 

     if (counter == 3) { 
      console.log("All done. That was three seconds."); 
      window.clearInterval(timer); 
      deferred.resolve(); 

     } else {    
      console.log("Not there yet. Counter at: " + counter); 
      deferred.notify(counter); 
     } 
     counter++; 
    }, 1000); 
    return deferred.promise(); 

} 

(function(){ 
    var timer = countThreeSeconds().done(function(){ 
    alert("done"); 
    }).progress(function(i){ 
    console.log("in progress...",i); 
    }); 

}()); 
+0

これは本当にいいです。そして、完璧な意味合いがあります。したがって、jquery ajaxのようなすべての遅延メソッドに自動的にアクセスする通常の関数は期待できませんでした。どうもありがとう! – 1252748

+0

最後のコンソールのカンマはどのように機能しますか?私は前にそれを見たことがありません。 – 1252748

+0

'console.log()'は無数の引数を受け取ります。複数のものをログに記録するか、各ログにラベルを付けることができます。です。 –

2

あなたは関数から何かを返すていないので、それは完全に有効なJSの行動です。関数上でdoneを使用できるようにするには、jQuery.Deferredオブジェクトを返します。このような

何か:

function countThreeSeconds() { 
    var defer = $.Deferred(function() { // do your stuff here }); 
    return defer.promise(); 
} 
+0

なぜ '$ .Deferred'に関数を渡していますか?それはあなたのコードが行く場所ではありません。 –

+0

@RocketHazmat関数内でそれを行うことに何も問題はありません。 http://pastebin.com/CWXWcmkS –

+0

@KevinB:私はドキュメントを見ました。あなたが正しいと思いますが、私は決してそれを見たことがありません。 –

0

トーマスのように、あなたはDeferredオブジェクト(とその約束)を実際に働かせることができます。

たとえば、countThreeSeconds()を未処理のより一般化された関数にすることができ、呼び出し元の関数ですべての進捗状況/完了報告を実行できます。

function countSeconds(n) { 
    var dfrd = $.Deferred(), 
     counter = 0, 
     timer = setInterval(function() { 
      counter++; 
      if (counter < n) { dfrd.notify(counter); } 
      else { dfrd.resolve(); } 
     }, 1000); 
    return { 
     promise: dfrd.promise(), 
     timer: timer 
    }; 
} 

(function() { 
    var timerObj = countSeconds(3); 
    timerObj.promise.progress(function(counter) { 
     console.log("Not there yet. Counter at: " + counter); 
    }).done(function() { 
     clearInterval(timerObj.timer); 
     console.log("All done. That was three seconds."); 
     alert("done"); 
    }); 
}()); 

したがって、別の関数が異なる値でcountSeconds()を呼び出すことができ、かつ、異なる進捗と完了状況を扱います。例えば

(function() { 
    var timerObj = countSeconds(10); 
    timerObj.promise.progress(function(counter) { 
     $("#message").text("Counter = " + counter); 
    }).done(function() { 
     clearInterval(timerObj.timer); 
     $("#message").text('Complete'); 
    }); 
}()); 
関連する問題