Mengapa janji jQuery mempunyai done(), tetapi janji Javascript yang didokumentasikan oleh Mozilla tidak? Bagaimana jika saya ingin mempunyai done() dalam JS?


Apakah perbezaan antara Promises dalam dokumen JavaScript Mozilla (lihat halaman API) dan Promises jQuery (lihat halaman API)?

Janji Mozilla nampaknya hanya mempunyai 2 kaedah: then dan catch. Janji jQuery nampaknya mempunyai lebih banyak kaedah, termasuk: then, done, dan fail. (dari sini)

Kenapa API JS di Mozilla tidak mempunyai done()? Bagaimana jika saya ingin mempunyai fungsi done() dalam JavaScript? Apa yang perlu saya lakukan?

Jawapan #1

Janji JavaScript Mozilla berdasarkan standard ES6, manakala janji jQuery adalah sesuatu yang dicipta sebelum ES6 dikeluarkan.

Berdasarkan pembacaan saya terhadap dokumentasi jQuery, ES6 then adalah setara dengan jQuery done.

Sebenarnya terdapat banyak perpustakaan janji, tetapi bagi saya ES6 adalah yang paling mudah difahami. Anda tidak memerlukan lebih daripada "then" dan "catch" dan ia sangat mudah untuk digabungkan menjadi satu siri operasi. Tambahkan dengan Promise.all untuk tugas selari dan 99% daripada apa yang anda perlukan sudah tercakup.

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

Beberapa perkara yang disokong oleh jQuery yang tidak terdapat dalam ES6 adalah beberapa jenis penyelesaian "progress".

Jawapan #2

API tertunda jQuery terlalu besar dan wujud sebelum perpustakaan janji. Setelah mereka menyedari betapa bergunanya janji, mereka menambah kaedah then (atau sebelum ini, pipe), walau bagaimanapun mereka gagal untuk melakukannya dengan betul 100%.

Kenapa API JS di Mozilla tidak mempunyai done()?

Ia sepenuhnya tidak perlu. Semua pelaksanaan yang serasi dengan Promises/A+ (yang termasuk ES6) hanya memerlukan satu kaedah: .then(). Ia sepenuhnya universal, anda boleh melakukan semuanya dengannya - ia adalah primitif bagi promises.

Bagaimana jika saya mahu mempunyai fungsi done() dalam JavaScript? Apa yang patut saya lakukan?

Baiklah, anda boleh melaksanakannya sendiri:

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

Tetapi seperti yang anda boleh lihat daripada itu, ia sebenarnya tidak begitu berguna. Ia tidak berantai, dan ia mengabaikan pengecualian, jadi anda sepatutnya hanya menggunakan then di mana-mana sahaja.