JavaScript'te Promise'lere Giriş
Callback modelinin kullanımının kolayca callback hell durumuna yol açtığını zaten biliyorsunuz. Bu nedenle JavaScript'e promise'lar (promise) adı verilen yeni bir model eklendi. Haydi bu modeli inceleyelim.
Bir promise, parametre olarak, içine asenkron kodumuzu yerleştirmemiz gereken bir fonksiyonun iletildiği bir nesneyi temsil eder:
let promise = new Promise(function() {
// asenkron kod
});
Gördüğünüz gibi, promise nesnesini
promise değişkenine kaydettim. Kodun
başka bir yerinde, bu promise oluşturulurken
yazılan asenkron kod tamamlandığında
çalıştırılacak kodu içeren bir fonksiyonu
ileterek bu değişkene then metodunu
uygulayabilirim:
promise.then(function() {
// asenkron kod tamamlandığında çalışacak
});
Kulağa kafa karıştırıcı gelebilir, bu yüzden bir örneğe bakalım. Diyelim ki şöyle bir asenkron kodum var:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
Bu kod için asenkron programlamanın temel
görevini çözmek istiyorum: Zamanlayıcı
tetikledikten sonra belirli bir kodu
çalıştırmak. Aynı zamanda bu kodu zamanlayıcının
içine yerleştirmek istemiyorum ve bu koda
bir şekilde result değişkenine yazdığım
sonucun ulaşmasını istiyorum. Aslında bu sorunu
önceki derslerde callback'ler ve abonelikler
aracılığıyla çözmüştük. Şimdi bunu promise'lerle
nasıl yapacağımıza bir bakalım.
İlk olarak, asenkron kodumuzu bir promise içine sarmamız gerekiyor:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Ancak bu yeterli değil. Asenkron kodumuzun sona erdiğini açıkça belirtmeliyiz. Bu konuda bize, belirtilirse fonksiyonun ilk parametresine otomatik olarak gelen özel bir tamamlanma fonksiyonu yardımcı olacak:
let promise = new Promise(function(resolve) { // parametreyi belirtiyoruz
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Tamamlanma fonksiyonunu kullanarak, promise'e asenkron kodun ne zaman sona erdiğini açıkça belirtebiliriz. Bunun için bu fonksiyonu istediğimiz yerde çağırmalıyız:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // promise'i tamamla
}, 3000);
});
Aynı zamanda, asenkron kodun bir sonucunu dışarıya iletmek istiyorsak, onu tamamlama fonksiyonumuza parametre olarak iletebiliriz:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // sonucu ilet
}, 3000);
});
Elbette ara değişkenden kurtulabiliriz:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
Şimdi başka herhangi bir yerde promise'imizin
then metodunu çağırabiliriz:
promise.then(function() {
// promise tamamlandığında tetiklenecek
});
Promise'in çalışma sonucu, belirtmeyi seçersek fonksiyonun ilk parametresine gelecektir:
promise.then(function(result) {
console.log(result); // sonuç dizisini yazdıracak
});
İçinde 5 saniyelik bir gecikme olan,
sonrasında promise'in herhangi bir metni
döndürerek tamamlanması gereken bir promise
yapın. Bu metni ekrana yazdırın.