Sebelum kami memulai pengantar formal, kami ingin melihat seperti apa janji JavaScript:
Salinan kode adalah sebagai berikut:
var p = janji baru (fungsi (resolve, reject) {
tekad ("halo dunia");
});
p.then (function (str) {
waspada (str);
});
1. Kemudian () mengembalikan janji bercabang
Apa perbedaan antara dua kode berikut?
Salinan kode adalah sebagai berikut:
// Bukti a
var p = janji baru (/*...*/);
p.then (func1);
p.then (func2);
// Bukti b
var p = janji baru (/*...*/);
p.then (func1)
.then (func2);
Jika Anda dengan hati-hati mempertimbangkan dua potong kode yang setara di atas, maka janji hanyalah serangkaian fungsi panggilan balik satu dimensi. Namun, ini bukan masalahnya. Masing -masing () panggilan mengembalikan janji bercabang. Oleh karena itu, di Exhibita, jika func1 () melempar pengecualian, func2 () masih disebut secara normal.
Di Exhibitb, jika func1 () melempar kesalahan, fun2 () tidak akan dipanggil karena panggilan pertama mengembalikan janji baru, yang akan ditolak di func1 (). Hasilnya adalah func2 () dilewati.
Ringkasan: Janji dapat menjadi garpu ke beberapa jalur, mirip dengan diagram alur yang kompleks.
2. Callback harus melewati hasilnya
Apa yang akan mendapatkan peringatan saat Anda menjalankan kode berikut?
Salinan kode adalah sebagai berikut:
var p = janji baru (fungsi (resolve, reject) {
tekad ("halo dunia");
});
p.then (function (str) {})
.then (function (str) {
waspada (str);
});
Peringatan di kedua () tidak menunjukkan apa pun. Ini karena fungsi panggilan balik, dalam konteks janji, tidak ada fungsi panggilan balik karena hasilnya berubah. Promise mengharapkan panggilan balik Anda untuk mengembalikan hasil yang sama atau hasil penggantian, yang kemudian diteruskan ke panggilan balik berikutnya.
Mirip dengan menggunakan Adpater untuk mengubah hasil, sebagai berikut:
Salinan kode adalah sebagai berikut:
var feettometres = function (ft) {return ft*12*0.0254};
var p = janji baru (/*...*/);
p.then (feettometres)
.then (function (meter) {
waspada (meter);
});
3. Hanya pengecualian dari lapisan sebelumnya yang bisa ditangkap
Apa perbedaan antara dua potong kode ini?
Salinan kode adalah sebagai berikut:
// Bukti a
janji baru (function (resolve, reject) {
tekad ("halo dunia");
})
.Kemudian(
function (str) {
melempar kesalahan baru ("uh oh");
},
belum diartikan
)
.Kemudian(
belum diartikan,
function (error) {
peringatan (kesalahan);
}
);
// Bukti b
janji baru (function (resolve, reject) {
tekad ("halo dunia");
})
.Kemudian(
function (str) {
melempar kesalahan baru ("uh oh");
},
function (error) {
peringatan (kesalahan);
}
);
Dalam potongan kode pertama, pengecualian pada yang pertama kali () dilemparkan dan akan ditangkap oleh yang kedua kemudian (), dan peringatan "uh oh" akan dipicu. Panduan ini satu -satunya pengecualian di level sebelumnya yang akan ditangkap.
Dalam potongan kode kedua, fungsi callback dan fungsi callback kesalahan berada pada level yang sama, yang berarti bahwa ketika pengecualian dilemparkan ke dalam panggilan balik, itu tidak akan ditangkap. Faktanya, panggilan balik kesalahan kode kedua hanya akan dilemparkan jika janji ditolak atau jika janji itu sendiri salah.
4. Kesalahan bisa dipulihkan
Dalam fungsi callback kesalahan, jika Anda tidak melemparkan kembali kesalahan, Promise mengasumsikan bahwa Anda telah pulih dari kesalahan dan terbalik ke keadaan terselesaikan. Dalam contoh berikutnya, "I'm Saved" akan ditampilkan karena callback kesalahan pada yang pertama kemudian () tidak melemparkan kembali pengecualian.
Salinan kode adalah sebagai berikut:
var p = janji baru (fungsi (resolve, reject) {
tolak (kesalahan baru ("pebkac"));
});
p.then (
belum diartikan,
function (error) {}
)
.Kemudian(
function (str) {
waspada ("Saya diselamatkan!");
},
function (error) {
peringatan ("Komputer Buruk!");
}
);
Janji dapat dilihat sebagai lapisan pada bawang. Masing -masing kemudian () menambahkan level lain ke bawang. Setiap level mewakili aktivitas yang diproses. Ketika hierarki selesai, hasilnya dianggap telah diperbaiki dan siap untuk hierarki berikutnya.
5. Janji bisa ditangguhkan
Karena Anda siap untuk dieksekusi dalam satu metode kemudian (), itu tidak berarti bahwa Anda tidak dapat menjeda dan menjalankan lainnya sebelumnya. Untuk menjeda janji saat ini, atau membiarkannya menunggu janji lain untuk menyelesaikan, cukup mengembalikan janji lain di kemudian ().
Salinan kode adalah sebagai berikut:
var p = janji baru (/*...*/);
p.then (function (str) {
if (! Loggedin) {
mengembalikan janji baru (/*...*/);
}
})
.then (function (str) {
waspada ("selesai.");
})
Dalam kode sebelumnya, prompt tidak akan muncul sampai janji baru diuraikan. Ini adalah cara yang nyaman untuk memperkenalkan lebih banyak dependensi di jalur kode asinkron yang ada. Misalnya, Anda mungkin menemukan bahwa sesi pengguna memiliki batas waktu dan Anda mungkin ingin menginisialisasi login kedua sebelum melanjutkan dengan jalur kode sebelumnya.
6. Janji -janji yang diselesaikan tidak akan segera dieksekusi
Apakah Anda akan mendapatkan kotak prompt saat menjalankan kode berikut?
Salinan kode adalah sebagai berikut:
fungsi runme () {
var i = 0;
janji baru (function (resolve) {
menyelesaikan();
})
.then (function () {
i += 2;
});
waspada (i);
}
Karena janji diuraikan segera dan kemudian () metode dieksekusi segera, Anda mungkin berpikir bahwa prompt 2 akan diselidiki. Namun, definisi janji mengharuskan semua panggilan dipaksakan asinkron. Oleh karena itu, prompt akan dihasilkan sebelum dimodifikasi.