How to convert a callback pattern to a deferred object?

I have a function that takes a callback function where I pass the data back. Can this transform into a deferred object for best practice?

Here is what I got:

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

Then I just use it like this:

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

How can I use it as a promise, while maintaining a cache approach?

 this.getChapters().done(function (data) { console.log(data); }); 
+6
source share
2 answers
 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

+3
source

I see that you have already accepted the answer, however, if you take a big mental leap and keep the promise of chapters instead of chapters themselves, then the code will be greatly simplified.

Nowadays this is probably the more common approach for a fetch / cache situation.

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

What is actually promised (chapters) will be determined by the value (s) returned by the Lawnchair and this.save , so you still need to do some work.

getChapters() will always return a promise, regardless of whether the data should be retrieved or already cached. Therefore, getChapters() can only be used with the concrete methods .then() , .done() , .fail() or .always() , for example:

 getChapters().then(fnLoad); 

You do not have another way to access chapters , but this is reasonable, because with any call to getChapters() you do not know whether it will follow the $.getJSON() branch or the simple return branch, from which identical promises are returned.

+2
source

Source: https://habr.com/ru/post/949405/


All Articles