De ce promisiunea jQuery are un done(), dar promisiunea JavaScript documentată de Mozilla nu are? Ce se întâmplă dacă vreau să am un done() în JS?


Care sunt diferențele dintre Promises în documentația JavaScript a Mozilla (vezi pagina API) și Promises în jQuery (vezi pagina API)?

Promisiunea Mozilla pare să aibă doar 2 metode: then și catch. Promisiunea jQuery pare să aibă mai multe metode, inclusiv: then, done și fail. (de aici)

De ce API-ul JS pe Mozilla nu are done()? Ce fac dacă vreau să am o funcționalitate done() în JavaScript? Ce trebuie să fac?

Răspuns #1

Promisiunile javascript ale Mozilla se bazează pe standardul ES6, în timp ce promisiunile jQuery au fost ceva creat înainte ca ES6 să fie lansat.

Pe baza lecturii mele a documentației jQuery, ES6 then este echivalent cu jQuery done.

De fapt, există o mulțime de biblioteci pentru promisiuni, dar pentru mine cea din ES6 este cea mai simplu de înțeles. Nu ai nevoie de mai mult decât „then” și „catch” și este foarte ușor să le legi împreună într-o secvență de operațiuni. Adaugă la asta Promise.all pentru sarcini paralele și 99% din ceea ce ai nevoie este acoperit.

return doSomething().then(function(result) {
  return doSomethingElse(result);
}).then(function(secondResult) {
  return doThirdSomething(secondResult);
}).catch(function(err) {
  console.log(err);
}).then(function(finalResult) {
  // a then after a catch is like a "finally" or "always"
  return finalResult;
}); 

Unele lucruri pe care jQuery le suportă și care nu sunt în ES6 sunt un fel de rezolvare „progres”.

Răspunsul #2

API-ul deferred al jQuery este supradimensionat și precede bibliotecile de promise-uri. Odată ce au realizat cât de utile sunt promise-urile, au adăugat o metodă then (sau anterior, pipe), totuși au eșuat să o facă 100% corect.

De ce API-ul JS de pe Mozilla nu are done()?

Este complet inutil. Toate implementările compatibile cu Promises/A+ (care includ ES6) au nevoie doar de o singură metodă: .then(). Este complet universal, poți face totul cu ea - este primitivul promisiunilor.

Ce se întâmplă dacă vreau să am o funcționalitate done() în JavaScript? Ce fac?

Ei bine, ai putea să o implementezi tu însuți:

Promise.prototype.done = function(cb) { // or function(...cbs) for (let cb of cbs) …
    this.then(cb).then(null, function(err) { /* ignore */ });
    return this;
};

Dar după cum poți vedea din asta, de fapt nu este foarte util. Nu se leagă în lanț și ignoră excepțiile, așa că ar trebui să folosești then peste tot.