2011-02-07 18 views
6

Tarayıcının 'bunu' düşündükleriyle ilgili bir sorun yaşıyorum. Aşağıdaki örnekte, pingMe() ifadesinin abc'de aranması 1 saniye bekleyecektir ve ardından tarayıcı Object DOMWindow'un 'func' yöntemine sahip olmadığını söyleyecektir. 'Bu', ABC (abc) sınıfının örneğine çözümlemek yerine, nesne dahil edilmemiş gibi DOMWindow'a gider. SetTimeout'un geri arama kapsamına göre nasıl çalıştığını açıkça anlamıyorum. Bu geri bildirimi nasıl yapabilirim önerileri başarılı?Coffeescript timer ve 'this' işaretçisi geri aramada

class ABC 
    @func = null 

    constructor: (func) -> 
    @func = func 

    pingMe: -> 
    setTimeout(doPing, 1000) 

    doPing = -> 
    @func() 

abc = new ABC -> 
    alert "HI" 
abc.pingMe() 
+1

hm, setTimeout satırını 'obj = this olarak değiştirerek; setTimeout ((-> obj.doPing()), 1000) 've doPing bildirimi' doPing: -> 'düzeltmek için görünüyor. CoffeeScript, bu senaryolarda normal JavaScript davranışı tutuyor gibi görünüyor. – Larry

cevap

10

Bu kodu çalışıyorum.

class ABC 
    @func = null 

    constructor: (func) -> 
    @func = func 

    pingMe: -> 
    setTimeout => 
    @doPing() 
    , 1000 

    doPing: -> 
    @func() 

abc = new ABC -> 
    alert "HI" 
abc.pingMe() 

Kişisel doping yöntemi diğerleri name: -> kullanmak oysa ben böyle değiştirdi, doPing = -> tanımlandı. pingMe, adlandırılmamış bir işlev oluşturmak için => kullanır ve işlevine bağlanmak için @doPing kullanır.

Bunun doğru olup olmadığından emin değilim, nadiren JavaScript kullanıyorum. Ama umarım daha fazla bakacak bir yön verebilir.

+0

evet öyle. '=>' bilgim eksikti. – Larry

0

Belki biraz daha açıklık için, bunun yerine "doPing" yöntemini bağlayabilirsiniz. Biraz daha temiz görünecek ve FWIW, neye ulaşmak istediğinizi daha iyi ifade ediyor.

class ABC 
    @func = null 

    constructor: (func) -> 
    @func = func 

    pingMe: -> 
    setTimeout => @doPing, 1000 

    doPing: => 
    @func() 

abc = new ABC -> 
    alert "HI" 
abc.pingMe() 
+0

Bunun, = = @doping() 'olması gerektiğine inanıyorum. '=> @ doPing', bağlı işlevi çağıran bir işlevi değil, sınır işlevini döndüren bir işlevi değerlendirir. Reiner'in cevabına bakınız. – joeytwiddle

1

Eğer ES5 ne yapacağını daha yakın olan alternatif bir çözümdür:

pingMe: -> 
    setTimeout (@doPing.bind @), 1000 

Not bind şudur:

pingMe: -> 
    setTimeout(@doPing.bind(@), 1000) 

veya parantez üzerine kaydetmek isterseniz ES5, yani sürüm 9'da IE'de sadece available.


Ayrıca denemek için her ne pahasına önlemek günaha de yapmanız gerekir, not:

setTimeout(@doPing.bind @, 1000) # BAD! 
     or 
    setTimeout @doPing.bind @, 1000  # BAD! 

olanların hem bind ikinci argüman olarak setTimeout sayı değil iletmemizdir!

İlgili konular