2013-04-18 29 views
7

jquery done() "ajax olmayan" işlevler üzerinde kullanabilir miyim? Böyle bir şey yapmaya çalıştığımda Uncaught TypeError: Cannot call method 'done' of undefined hatasını aldım. Eğer işlevinden şey dönen değiliz yana"ajax olmayan" işlevinde yapılan jquery işlevini kullanın

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

}()); 

Teşekkür

JSBIN

+3

Gördüğünüz gibi, yapamazsınız. jQuery ile ilgisi yoktur. 'Undefined' üzerinde bir yöntemi hiçbir zaman arayamazsınız. jQuery yöntemleri her yerde sadece sihirli görünmez * (şükürler olsun) *. Bunları jQuery kitaplığında ve jQuery'nin API'sinde açıklandığı gibi tanımlanan belirli nesnelere çağırabilirsiniz. –

cevap

13

olmayan ajax fonksiyonu bir söz nesneyi döndürmek olun.

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

Bu gerçekten çok hoş. Ve mükemmel bir anlam ifade ediyor. Şu anda bariz bir şekilde normal bir fonksiyonun otomatik olarak jquery ajax gibi tüm ertelenmiş yöntemlere erişmesini bekleyemem. Çok teşekkürler! – 1252748

+0

Son konsoldaki virgül nasıl çalışır? Bunu daha önce hiç görmedim .. – 1252748

+0

'console.log()' sonsuz bir sayıyı (sanırım) argüman sayısını kabul eder, sadece birden fazla şeyi günlüğe kaydetmenize ya da her bir günlüğünü etiketlemenize izin verir, böylece ne olduğunu bilirsiniz. olduğunu. –

2

, bu tamamen geçerli JS davranış. done işlevini işlevde kullanabilmek için, jQuery.Deferred nesnesini buradan döndürün. Böyle

şey:

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

Neden bir işlevi "$ .Deferred" konumuna geçiriyorsunuz? Bu senin * kodunun nereye gittiği * değil. –

+0

@RocketHazmat İşlevde bunu yapmakta yanlış bir şey yok. http://pastebin.com/CWXWcmkS –

+0

@KevinB: Sadece dokümanlara baktım. Sanırım haklısın, ama ben hiç böyle bir şey yapmadığını gördüm. –

0

Thomas, böyle bir şeyle, bir Deferred nesnesini (ve sözünü) sizin için gerçekten çalıştırabilirdiniz. Örneğin, countThreeSeconds()'u daha ham, daha genelleştirilmiş bir işlev haline getirebilir ve arama işlevinde gerçekleştirilen tüm ilerleme/tamamlanmış raporlamaları gerçekleştirebilirsiniz.

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"); 
    }); 
}()); 

Böylece başka fonksiyon farklı bir değerle countSeconds() diyebiliriz ve farklı ilerleme ve tamam durumlarla başa. Örneğin

:

(function() { 
    var timerObj = countSeconds(10); 
    timerObj.promise.progress(function(counter) { 
     $("#message").text("Counter = " + counter); 
    }).done(function() { 
     clearInterval(timerObj.timer); 
     $("#message").text('Complete'); 
    }); 
}()); 
İlgili konular