Janji memiliki status, mereka mulai tertunda dan dapat puas dengan:
- memenuhi artinya bahwa perhitungan selesai dengan sukses.
- ditolak artinya penghitungan gagal.
Fungsi janji pengembalian tidak boleh dibuang , mereka harus mengembalikan penolakan sebagai gantinya. Melempar dari fungsi pengembalian janji akan memaksa Anda untuk menggunakan a } catch {
dan a .catch
. Orang-orang yang menggunakan API yang dijanjikan tidak berharap untuk membuang janji. Jika Anda tidak yakin bagaimana API async bekerja di JS - silakan lihat jawaban ini terlebih dahulu.
1. Beban DOM atau acara satu kali lainnya:
Jadi, membuat janji umumnya berarti menentukan kapan mereka puas - itu berarti ketika mereka pindah ke fase yang dipenuhi atau ditolak untuk menunjukkan data tersedia (dan dapat diakses dengan .then
).
Dengan implementasi janji modern yang mendukung Promise
konstruktor seperti ES6 asli menjanjikan:
function load() {
return new Promise(function(resolve, reject) {
window.onload = resolve;
});
}
Anda kemudian akan menggunakan janji yang dihasilkan seperti:
load().then(function() {
// Do things after onload
});
Dengan pustaka yang mendukung ditangguhkan (Mari gunakan $ q untuk contoh ini di sini, tetapi kami juga akan menggunakan jQuery nanti):
function load() {
var d = $q.defer();
window.onload = function() { d.resolve(); };
return d.promise;
}
Atau dengan jQuery seperti API, mengaitkan peristiwa yang terjadi sekali:
function done() {
var d = $.Deferred();
$("#myObject").once("click",function() {
d.resolve();
});
return d.promise();
}
2. Panggilan balik polos:
API ini agak umum karena ... panggilan balik umum di JS. Mari kita lihat kasus umum memiliki onSuccess
dan onFail
:
function getUserData(userId, onLoad, onFail) { …
Dengan implementasi janji modern yang mendukung Promise
konstruktor seperti ES6 asli menjanjikan:
function getUserDataAsync(userId) {
return new Promise(function(resolve, reject) {
getUserData(userId, resolve, reject);
});
}
Dengan pustaka yang mendukung ditangguhkan (Mari gunakan jQuery untuk contoh ini di sini, tetapi kami juga menggunakan $ q di atas):
function getUserDataAsync(userId) {
var d = $.Deferred();
getUserData(userId, function(res){ d.resolve(res); }, function(err){ d.reject(err); });
return d.promise();
}
jQuery juga menawarkan $.Deferred(fn)
formulir, yang memiliki keuntungan memungkinkan kita untuk menulis ekspresi yang sangat mirip dengan new Promise(fn)
formulir, sebagai berikut:
function getUserDataAsync(userId) {
return $.Deferred(function(dfrd) {
getUserData(userId, dfrd.resolve, dfrd.reject);
}).promise();
}
Catatan: Di sini kita mengeksploitasi fakta bahwa jQuery yang ditangguhkan resolve
dan reject
metode "dapat dilepas"; yaitu. mereka terikat pada instance dari jQuery.Deferred (). Tidak semua lib menawarkan fitur ini.
3. Callback gaya simpul ("nodeback"):
Callback gaya simpul (nodebacks) memiliki format tertentu di mana callback selalu menjadi argumen terakhir dan parameter pertamanya adalah kesalahan. Pertama mari kita promisikan secara manual:
getStuff("dataParam", function(err, data) { …
Untuk:
function getStuffAsync(param) {
return new Promise(function(resolve, reject) {
getStuff(param, function(err, data) {
if (err !== null) reject(err);
else resolve(data);
});
});
}
Dengan ditangguhkan Anda dapat melakukan hal berikut (mari kita gunakan Q untuk contoh ini, meskipun Q sekarang mendukung sintaks baru yang harus Anda sukai ):
function getStuffAsync(param) {
var d = Q.defer();
getStuff(param, function(err, data) {
if (err !== null) d.reject(err);
else d.resolve(data);
});
return d.promise;
}
Secara umum, Anda tidak boleh terlalu banyak menjanjikan hal-hal secara manual, sebagian besar perpustakaan janji yang dirancang dengan mempertimbangkan Node serta janji bawaan di Node 8+ memiliki metode bawaan untuk menjanjikan serangan balik. Sebagai contoh
var getStuffAsync = Promise.promisify(getStuff); // Bluebird
var getStuffAsync = Q.denodeify(getStuff); // Q
var getStuffAsync = util.promisify(getStuff); // Native promises, node only
4. Seluruh perpustakaan dengan panggilan balik gaya simpul:
Tidak ada aturan emas di sini, Anda menjanjikannya satu per satu. Namun, beberapa implementasi janji memungkinkan Anda melakukan ini secara massal, misalnya di Bluebird, mengonversi API nodeback ke API janji sesederhana:
Promise.promisifyAll(API);
Atau dengan janji asli di Node :
const { promisify } = require('util');
const promiseAPI = Object.entries(API).map(([key, v]) => ({key, fn: promisify(v)}))
.reduce((o, p) => Object.assign(o, {[p.key]: p.fn}), {});
Catatan:
- Tentu saja, ketika Anda berada di
.then
pawang Anda tidak perlu menjanjikan sesuatu. Mengembalikan janji dari .then
pawang akan menyelesaikan atau menolak dengan nilai janji itu. Melempar dari .then
pawang juga merupakan praktik yang baik dan akan menolak janji - ini adalah janji keselamatan lemparan yang terkenal.
- Dalam
onload
kasus aktual , Anda harus menggunakan addEventListener
daripada onX
.