Vaatlerin durumu vardır, beklemede olarak başlarlar ve şunlara yerleşebilirler:
- yerine hesaplama başarıyla tamamlandı anlamına gelir.
- hesaplama başarısız olduğu için reddetti .
Söz döndüren işlevler asla atmamalı , bunun yerine reddetmeleri döndürmelidir. Bir söz dönen işlevinden Fırlatma a ikisini de kullanmak için zorlar } catch {
ve bir .catch
. Vaat edilmiş API'leri kullanan kişiler vaatlerin verilmesini beklemezler. Zaman uyumsuz API'ların JS'de nasıl çalıştığından emin değilseniz - lütfen önce bu cevaba bakın .
1. DOM yükü veya başka bir defalık etkinlik:
Bu nedenle, vaatler oluşturmak genellikle ne zaman yerleşeceklerini belirtmek anlamına gelir - bu da verilerin kullanılabilir olduğunu (ve bunlara erişilebildiğini .then
) belirtmek için yerine getirilen veya reddedilen aşamaya geçtikleri anlamına gelir .
Promise
Doğal ES6 vaatleri gibi kurucuyu destekleyen modern vaat uygulamaları ile :
function load() {
return new Promise(function(resolve, reject) {
window.onload = resolve;
});
}
Daha sonra ortaya çıkan sözü aşağıdaki gibi kullanırsınız:
load().then(function() {
// Do things after onload
});
Ertelemeyi destekleyen kitaplıklarla (Burada bu örnek için $ q kullanalım, ancak daha sonra jQuery kullanacağız):
function load() {
var d = $q.defer();
window.onload = function() { d.resolve(); };
return d.promise;
}
Veya API gibi bir jQuery ile bir kez gerçekleşen bir etkinliğe bağlanma:
function done() {
var d = $.Deferred();
$("#myObject").once("click",function() {
d.resolve();
});
return d.promise();
}
2. Düz geri arama:
Bu API'lar oldukça yaygındır çünkü JS'de geri aramalar yaygındır. Ortak sahip olma durumuna bakalım onSuccess
ve onFail
:
function getUserData(userId, onLoad, onFail) { …
Promise
Doğal ES6 vaatleri gibi kurucuyu destekleyen modern vaat uygulamaları ile :
function getUserDataAsync(userId) {
return new Promise(function(resolve, reject) {
getUserData(userId, resolve, reject);
});
}
Ertelemeyi destekleyen kütüphanelerle (burada bu örnek için jQuery kullanalım, ancak yukarıda $ q da kullandık):
function getUserDataAsync(userId) {
var d = $.Deferred();
getUserData(userId, function(res){ d.resolve(res); }, function(err){ d.reject(err); });
return d.promise();
}
jQuery , aşağıdaki gibi $.Deferred(fn)
, new Promise(fn)
formu çok yakından taklit eden bir ifade yazmamıza olanak sağlayan bir form da sunar :
function getUserDataAsync(userId) {
return $.Deferred(function(dfrd) {
getUserData(userId, dfrd.resolve, dfrd.reject);
}).promise();
}
Not: Burada, bir jQuery ertelenmiş yöntem resolve
ve reject
yöntemlerin "ayrılabilir" olduğu gerçeğini kullanırız ; yani. jQuery.Deferred () örneğine bağlıdırlar . Tüm kütüphaneler bu özelliği sunmaz.
3. Düğüm stili geri arama ("düğüm"):
Düğüm stili geri çağrıları (düğüm geri çağrıları), geri çağrıların her zaman son argüman olduğu ve ilk parametresinin bir hata olduğu belirli bir biçime sahiptir. İlk önce manuel olarak söz verelim:
getStuff("dataParam", function(err, data) { …
Kime:
function getStuffAsync(param) {
return new Promise(function(resolve, reject) {
getStuff(param, function(err, data) {
if (err !== null) reject(err);
else resolve(data);
});
});
}
Ertelemelerle aşağıdakileri yapabilirsiniz (Q şimdi tercih etmeniz gereken yeni sözdizimini desteklese de, bu örnek için Q kullanalım ):
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;
}
Genel olarak, şeyleri çok fazla elle vaat etmemelisiniz, Düğüm göz önünde bulundurularak tasarlanan çoğu söz kitaplığı ve Düğüm 8+'daki yerel sözlerin düğüm geri dönüşlerini vaat etmek için yerleşik bir yöntemi vardır. Örneğin
var getStuffAsync = Promise.promisify(getStuff); // Bluebird
var getStuffAsync = Q.denodeify(getStuff); // Q
var getStuffAsync = util.promisify(getStuff); // Native promises, node only
4. Düğüm stili geri çağrıları olan bütün bir kütüphane:
Burada altın bir kural yok, onları tek tek söz ediyorsunuz. Bununla birlikte, bazı vaat uygulamaları bunu örneğin Bluebird'de toplu olarak yapmanıza izin verir, bir geri dönüş API'sini bir söz API'sına dönüştürmek şu kadar basittir:
Promise.promisifyAll(API);
Veya ile yerli vaatler içinde Düğüm :
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}), {});
Notlar:
- Tabii ki, bir
.then
işleyicide olduğunuzda şeyleri vaat etmeniz gerekmez. Bir .then
işleyiciden bir sözün geri verilmesi söz konusu değerin değerine çözümlenecek veya reddedilecektir. Bir .then
işleyiciden atmak da iyi bir uygulamadır ve sözünü reddedecektir - bu ünlü söz atma güvenliği.
- Gerçek bir
onload
durumda, kullanmak addEventListener
yerine kullanmalısınız onX
.