2013-07-14 19 views
6

Mam funkcję, która akceptuje funkcję zwrotną, w której przekazuję dane z powrotem. Czy można to przekształcić w obiekt odroczony, aby uzyskać lepszą praktykę?Jak przekonwertować próbkę oddzwonienia na obiekt odroczony?

Oto co mam:

var chapters; 
    var getChapters = function (fnLoad) { 
     //CACHE DATA IF APPLICABLE 
     if (!chapters) { 
      //CALL JSON DATA VIA AJAX 
      $.getJSON('/chapters.txt') 
       .done(function (json) { 
        //STORE DATA IN LOCAL STORAGE 
        chapters = Lawnchair(function() { 
         this.save(json, function (data) { 
          //CALL CALLBACK ON DATA 
          fnLoad(data); 
         }); 
        }); 
       }); 
     } else { 
      //RETURN ALREADY CREATED LOCAL STORAGE 
      chapters.all(function (data) { 
       //CALL CALLBACK ON DATA 
       fnLoad(data); 
      }); 
     } 
    }; 

Potem po prostu używać go tak:

this.getChapters(function (data) { 
    console.log(data); 
}); 

Jak mogę używać go jak obietnica choć przy zachowaniu podejścia cache?

this.getChapters().done(function (data) { 
    console.log(data); 
}); 
+0

Metody ajax jQuery's rozszerzają obiekt odroczony. Już go używasz ... –

+0

Ale zauważ, że manipuluję danymi i korzystam z "Lawnchair" gdzieś pośrodku przed przekazaniem danych, więc nie mogę zwrócić obiektu ajax poprawnie? – TruMan1

+0

Dlaczego twoje komentarze są we wszystkich limitach? – Eric

Odpowiedz

3
var chapters; 
var getChapters = function (fnLoad) { 
    var d = new $.Deferred(); 
    //CACHE DATA IF APPLICABLE 
    if (!chapters) { 
     //CALL JSON DATA VIA AJAX 
     $.getJSON('/chapters.txt') 
      .done(function (json) { 
       //STORE DATA IN LOCAL STORAGE 
       chapters = Lawnchair(function() { 
        this.save(json, function (data) { 
         //CALL CALLBACK ON DATA 
         d.resolve(data); 
        }); 
       }); 
      }) 
      .fail(function() { d.reject(); }); 
    } else { 
     //RETURN ALREADY CREATED LOCAL STORAGE 
     chapters.all(function (data) { 
      //CALL CALLBACK ON DATA 
      d.resolve(data); 
     }); 
    } 
    return d.promise(); 
}; 

Relevant example

2

widzę już zaakceptowane odpowiedź, jednak jeśli wziąć duży skok umysłowego i przechowywać obietnicę chapters zamiast chapters siebie, wtedy kod będzie znacznie uprościć .

W dzisiejszych czasach jest to prawdopodobnie bardziej ogólnie przyjęte podejście do sytuacji "pobierania/buforowania".

var chapters_promise; 
var getChapters = function() { 
    //Cache data if applicable and return promise of data 
    if (!chapters_promise) 
     chapters_promise = $.getJSON('/chapters.txt').then(Lawnchair).then(this.save); 
    return chapters_promise; 
}; 

Co faktycznie jest obiecane (rozdziały) zostanie określona przez wartość (s) zwracany przez funkcje Lawnchair i this.save, więc jeszcze trochę do zrobienia.

getChapters() zawsze zwróci obietnicę, niezależnie od tego, czy dane muszą zostać pobrane, czy już jest w pamięci podręcznej. Dlatego getChapters() może być używany tylko z metod obietnica .then(), .done(), .fail() lub .always(), na przykład:

getChapters().then(fnLoad); 

Nie masz inny sposób dostępu do chapters ale to jest uzasadnione, ponieważ w każdym wezwaniu getChapters(), don Nie wiadomo, czy będzie ona następować po gałęzi $.getJSON(), czy prostej gałęzi return, obie zwracają identyczną obietnicę.

Powiązane problemy