JavaScript Promises. Nedir bu Promise?!

JavaScript Promises. Nedir bu Promise?!


Reviewed by:
Rating:
5
On 12/25/2017
Last modified:02/28/2018

Summary:

Javascript Promise ES5 ile birlikte daha çok görülmeye başlanmış ve web dünyasında fazlasıyla kullanılmaya başlamıştır.

Alışık olduğumuz gibi eş zamanlı programlama(synchronous programming) hata düzeltme(debug) açısından daha kolaydır fakat asenkron programlama esneklik ve performans açısından genel olarak daha iyidir. Çok fazla sayıda isteğin aynı anda sunucuya geldiğini düşünelim. Bu kadar isteği nasıl halledeceğiz ? İşte tam bu noktada JavaScript dünyasında Promise yapısı devreye giriyor. Hadi gelin hep birlikte promise yapısına ve nasıl kullanıldığına bir göz atalım.

 

Promise İlk Bakış

Aslında XMLHttpRequest API asenkron fakat Promise API’sini kullanmıyor. Bunun yanı sıra promise kullanan birkaç tane native API de var.

  • Battery API
  • fetch API
  • ServiceWorkers

Promise yapısı gün geçtikçe daha da yaygınlaşıyor ve yaygınlaşmaya devam edecek. Bu yüzden front-end geliştiricilerin bir an önce bu yapıyla, tam anlamıyla kavraması iyi olacaktır. Ayrıca,Node.js programlama dilinin, promise yapısı için bir başka dünyası da diyebiliriz (promise yapısı dilin çekirdeğinde var olduğu için).

Ayrıca, promise yapısını test etmek muhtemelen düşündüğünüzden de basit olacaktır çünkü setTimeOut asenkron görevler için kullanılabilir.

Basit Şekilde Promise Kullanımı

new Promise() yapısı sadece setTimeout veya XMLHttpRequest yapılarının olduğu gibi  durumlarda kullanılmalıdır. new anahtar kelimesi ile oluşturulan promise geriye resolve ya da reject olarak geri döner(callback).


var p = new Promise(function(resolve, reject) {
	
	// Do an async task async task and then...

	if(/* good condition */) {
		resolve('Success!');
	}
	else {
		reject('Failure!');
	}
});

p.then(function() { 
	/* do something with the result */
}).catch(function() {
	/* error :( */
})

 

Callback içinde resolve veya reject anahtar kelimeleri duruma göre manuel olarak geliştirici tarafından çağrılır. Daha gerçekçi bir örnek vermek gerekirse XMLHttpRequest çağrısını promise tabanlı bir çağrıya çevirerek gösterelim.

 


function get(url) {
  // Return a new promise.
  return new Promise(function(resolve, reject) {
    // Do the usual XHR stuff
    var req = new XMLHttpRequest();
    req.open('GET', url);

    req.onload = function() {
      // This is called even on 404 etc
      // so check the status
      if (req.status == 200) {
        // Resolve the promise with the response text
        resolve(req.response);
      }
      else {
        // Otherwise reject with the status text
        // which will hopefully be a meaningful error
        reject(Error(req.statusText));
      }
    };

    // Handle network errors
    req.onerror = function() {
      reject(Error("Network Error"));
    };

    // Make the request
    req.send();
  });
}

// Use it!
get('story.json').then(function(response) {
  console.log("Success!", response);
}, function(error) {
  console.error("Failed!", error);
});

Bazı durumlarda asenkron görevleri promise içinde tamamlamanız gerekmez(eğer mümkünse). Ancak yine de geriye bir Promise döndürmek en iyisi olacaktır çünkü Promise yapısına her zaman güvenebilirsiniz. Bu gibi durumlarda, new anahtar sözcüğü olmadan basitçe Promise.resolve() veya Promise.reject() kullanılır.


var userCache = {};

function getUserDetail(username) {
  // In both cases, cached or not, a promise will be returned

  if (userCache[username]) {
  	// Return a promise without the "new" keyword
    return Promise.resolve(userCache[username]);
  }

  // Use the fetch API to get the information
  // fetch returns a promise
  return fetch('users/' + username + '.json')
    .then(function(result) {
      userCache[username] = result;
      return result;
    })
    .catch(function() {
      throw new Error('Could not find user: ' + username);
    });
}

Promise yapısı her zaman geriye cevap döndürdüğü için then ve catch methodlarını kullanabiliriz.

then

Promise yapısı, then methodu ile kullanilabilir. Böylelikle geriye dönen cevaba göre aksiyon alabilirsiniz. İlk olarak çağrılan then methodu resolve ile geriye dönen değeri alır.


new Promise(function(resolve, reject) {
	// A mock async action using setTimeout
	setTimeout(function() { resolve(10); }, 3000);
})
.then(function(result) {
	console.log(result);
});

// From the console:
// 10

then methodu, promise resolve olduğu durumda tetiklenir. Ayrıca, then zincirlenerek de kullanılabilir.


new Promise(function(resolve, reject) { 
	// A mock async action using setTimeout
	setTimeout(function() { resolve(10); }, 3000);
})
.then(function(num) { console.log('first then: ', num); return num * 2; })
.then(function(num) { console.log('second then: ', num); return num * 2; })
.then(function(num) { console.log('last then: ', num);});

// From the console:
// first then:  10
// second then:  20
// last then:  40

Her then methodu bir öncekinin geriye döndürdüğü değeri alır.

Eğer bir promise çoktan resolve durumundaysa fakat then tekrar çağrıldıysa, callback anında yürütülür. Eğer promise reject durumundaysa ve then methodu çağrıldıysa callback asla yürütülmez.

catch

catch methodu; promise reject olduğu durumda kullanılır.


new Promise(function(resolve, reject) {
	// A mock async action using setTimeout
	setTimeout(function() { reject('Done!'); }, 3000);
})
.then(function(e) { console.log('done', e); })
.catch(function(e) { console.log('catch: ', e); });

// From the console:
// 'catch: Done!'

reject methoduna ne göndereceğiniz tamamen size bağlıdır. Genel olarak Error , catch methoduna gönderilir.

Örneğin : reject(Error('Data could not be found'));

Promise.all

Bazı durumlarda birden fazla asenkron çağrı yapmanız gerekebilir ve bu çağrıların tamamı bittiğinde bir cevap döndürmek isteyebilirsiniz. İşte tam bu noktada Promise.all yapısı devreye giriyor. Promise.all methodu, promise yapılarından oluşan bir dizi alır ve hepsi resolve durumunda olduğu zaman çağrılır.


Promise.all([promise1, promise2]).then(function(results) {
	// Both promises resolved
})
.catch(function(error) {
	// One or more promises was rejected
});

Promise.all methodunu daha iyi anlamak için birden fazla AJAX çağrısı(fetch API ile) yaptığımız durum düşünülebilir.


var request1 = fetch('/users.json');
var request2 = fetch('/articles.json');

Promise.all([request1, request2]).then(function(results) {
	// Both promises done!
});

Tabii ki Promise reject olduğu durumda ise uğraşmak biraz zor olabiliyor. Eğer herhangi bir promise reject olduysa ilk catch methodu çağrılır.


var req1 = new Promise(function(resolve, reject) { 
	// A mock async action using setTimeout
	setTimeout(function() { resolve('First!'); }, 4000);
});
var req2 = new Promise(function(resolve, reject) { 
	// A mock async action using setTimeout
	setTimeout(function() { reject('Second!'); }, 3000);
});
Promise.all([req1, req2]).then(function(results) {
	console.log('Then: ', results);
}).catch(function(err) {
	console.log('Catch: ', err);
});

// From the console:
// Catch: Second!

Promise Yapısına Alışmak

Promise yapıları, son zamanda oldukça sıcak bir konu durumunda. Başta Javascript framework durumunda olan bu yapı şimdi programlama dilinin yapısı haline gelmiş durumda. Buna bağlı olarak Promise yapısını web tarafında daha çok görebileceğimizi varsaymak yanlış olmaz.

Promise yapılarına alışmak biraz zaman alabilir fakat alıştığınızda ne kadar güçlü ve muhteşem olduklarını göreceksiniz.


Paylaş :

Full Stack Developer · Yazılım Tutkunu · Fikir, kod ve teknoloji Daha fazlası için hakkımda sayfasını ziyaret edebilirsiniz.



Bu yazı hakkındaki görüşünü benimle paylaşmaya ne dersin ?


Email adresiniz yayınlanmayacaktır.

Yorum yap butonuna
  bastıktan sonra yorumunuz gönderilecektir. Yorumunuz incelenip onaylandıktan sonra diğer ziyaretçilerimiz tarafından da görünecektir. Lütfen, yorum yaparken saygı çerçevesinde ve hakaret etmeden yorum yapmaya özen gösteriniz.

Bu yorumu göndererek bu uyarıları okuduğumu ve kabul ettiğimi onaylıyorum.

This site uses Akismet to reduce spam. Learn how your comment data is processed.