2013-07-14 20 views
6

我有一個函數接受一個回調函數,我將數據傳回去了。可以將它轉換爲延期對象以便更好地練習嗎?如何將回調示例轉換爲延期對象?

這裏是我的了:

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

然後,我只是用這樣的:

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

我如何使用它像一個承諾,雖然同時保持高速緩存的方法呢?

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

jQuery的ajax方法擴展了延遲對象。您已經在使用它... –

+0

但是請注意,我在操縱數據並在傳回數據之前在中間的某處使用「Lawnchair」,因此我無法返回ajax對象? – TruMan1

+0

爲什麼你的評論全部大寫? – Eric

回答

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

我看你已經接受了答案,但如果你把一個大的精神飛躍,存儲chapters代替chapters承諾自己,那麼代碼將顯著簡化。

現在,這可能是「取/緩存」情況下更普遍採用的方法。

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

什麼是真正承諾(章節)將通過功能Lawnchairthis.save回來,所以你仍然有一些工作要做值(S)來確定。

getChapters()將始終返回承諾,無論數據是否需要提取或已被緩存。因此,getChapters()只能與承諾方法.then().done().fail().always()使用,例如:

getChapters().then(fnLoad); 

你有沒有其他的方式來訪問chapters但這是合理的,因爲在getChapters()任何電話,你不不知道它是否會遵循$.getJSON()分支或簡單的return分支,兩者都返回相同的承諾。