14 Nisan 2013 Pazar

Windows 8 Uygulamalarında Promise Kullanımı

1 yorum

     Merhaba arkadaşlar, geçen hafta sizlere Application Bar ve Message Dialog kullanımından bahsetmiştim. Bu hafta da Windows 8 JavaScript uygulamaları geliştirirken Promise kullanımından bahsedeceğim. Promise JavaScript uygulamalarında asenkron uygulamalar geliştirirken kullanılır. Bu yüzden öncelikler sizlere asenkron programlama nedir bundan kısaca bahsetmek istiyorum ki konuya geçmeden önce kafamızda bazı şeyler oluşsun.

     Asenkron programlama uygulamalarımızın belirli bir süre içerisinde cevap verdiği noktalarda oluşmaktadır.  Örneğin; internet üzerinde bir Http isteği atarken uygulamanın internete bağlanması ve gelecek cevabı beklemesi gerekir. Bu işlem biraz zaman alabilir ve bu zaman zarfında eğer asenkron programlama yapmazsak kullanıcı başka bir işlem yapamaz ve bu da uygulamalarımızda kullanıcı kaybetmemize sebep olabilir. Aynı anda başka işlemler yapabilmek istiyorsak asenkron programlama yapmamız gerekir.



     Ufaktan Promise nasıl kullanılır başlayalım. İlk olarak değinmek istediğim nokta 'then' metodu. Promise'in 'then' metodu vardır ve ve bu metod asenkron yapılan işlerde başarılı olarak dönen işleri ve başarısız olan işleri ele alır(resolvedHandler, rejectedHandler). Ayrıca ilk başlangıçta Promise'i bir objeye eşitlememiz gerekir. Aşağıdaki koda bakarsak daha anlaşılır olacaktır:

 var Promise = function () {  
 /* promise tanıtımı */  
 };  

     Bu kısımda Promise objemizi tanıttık.

 Promise.prototype.then = function (onResolved, onRejected) {  
 /* geçişlere göre metotları çağırma (başarılı, başarısız asenkron işlemler) */  
 };  

     Bu kısımda da gerektiğinde çağrılmak üzere asenkron işlemimizin başarılı olup olmama durumlarına göre 'then' metodumuzu belirledik.


 Promise.prototype.resolve = function (value) {  
 /* başarıyla tamamlanmış işlemler için */  
 };  

     Eğer asenkron işlem yapma işimiz başarı ile tamamlandı ise yukarıdaki metod çalışıyor ve ona göre yapmak istediklerimizi bu metod içerisinde belirtebiliyoruz.


 Promise.prototype.reject = function (error) {  
 /* reddedilen işlem sonucu için */  
 };  

     Eğer asenkron işlemimiz bazı nedenlerden dolayı reddedildi ise yukarıdaki metod çağırılıyor ve bu metodda işlemin iptali sonucunda neler yapmak istiyorsak onları belirliyoruz. Basit bir örnek üzerinden gidecek olursak:


 function searchTwitter(term) {  
 var url, xhr, results, promise;  
 url = 'http://search.twitter.com/search.json?rpp=100&q=' + term;  
 promise = new Promise();  
 xhr = new XMLHttpRequest();  
 xhr.open('GET', url, true);  
 xhr.onload = function (e) {  
 if (this.status === 200) {  
 results = JSON.parse(this.responseText);  
 promise.resolve(results);  
 }  
 };  
 xhr.onerror = function (e) {  
 promise.reject(e);  
 };  
 xhr.send();  
 return promise;  
 }  
 function loadTweets() {  
 var container = document.getElementById('container');  
 searchTwitter('#orcundanismaz').then(function (data) {  
 data.results.forEach(function (tweet) {  
 var el = document.createElement('li');  
 el.innerText = tweet.text;  
 container.appendChild(el);  
 });  
 }, handleError);  
 }  

     Örneğin yukarıdaki kod bloğunda iki adet metod tanımladık. İlk metod içerisinde Twitter'a bir 'Get' işlemi tanımladık ve bu işlem içerisinde parametre olarak aratmak istediğimiz kelimeyi geçtik. Metod çağırıldığında bize gelen sonuçlar asenkron bir şekilde ayrıştırılıp kullanıcıya gösterilecek. 'loadTweets' metodunda ise sonuçlarımızı bir liste içerisinde gösterme işlemini yaptık. Twitter'a yapılan isteği asenkron bir şekilde yaptık ki kullanıcılar bu zaman zarfı içerisinde başka etkileşime geçebilsinler. Herhangi bir hata sırasında Promise için 'reject' metodunu çağırdık.

     Bu örnekte bir adet istek yaptık. Eğer birden fazla istek yapmak istiyorsak o zaman Promise'in 'when' metodunu kullanarak bunları sıra ile yapabiliriz. Bir işlem tamamlandığında veya reddedildiğinde direk olarak ikinci işlemden devam etme mantığı ile çalışır(fork-join).


 var container, promise1, promise2;  
 container = document.getElementById('container');  
 promise1 = searchTwitter('#IE10');  
 promise2 = searchTwitter('#IE9');  
 Promise.when(promise1, promise2).then(function (data1, data2) {  
 /* Reshuffle due to date */  
 var totalResults = concatResults(data1.results, data2.results);  
 totalResults.forEach(function (tweet) {  
 var el = document.createElement('li');  
 el.innerText = tweet.text;  
 container.appendChild(el);  
 });  
 }, handleError);  

   
     Yukarıda gördüğümüz gibi Twitter'da istenilen aram sonuçlarını getiren metodumuz iki kere çağırıldı ve her biri bir Promise objesine atandı. 'When' metodu ile de bunlar belirli bir sıraya alındı ve işlemlerin buna göre yapılması sağlanarak kullanıcıya arama sonuçları görüntülenmiş oldu.

     Promise kullanımındaki temel metodlara aşağıdan erişebilirsiniz:


 var p = new Promise(initCallback)   
//promise tanımlama 
 p.get_isComplete()   
 // Promise'in tamamlanığ tamamlanmadığını kontrol etmek için
  
 p.get_value()  
 // Promise'in değerini getirmek için 
 p.call(name, params)  
 // name adlı fonkisyonu çağıran promise 
 
 p.when(fulfillPromise, breakPromise, context)  
 // birden fazla istek olduğunda kullanılan metod
 p.whenOnly(fulfillPromise, breakPromise, context)  
  
 p.join(promises)  
 // bütün promiseler tamamlandığında yeni bir promise eklemek için
 Promise.whenOnly(promise, fulfillPromise, breakPromise, context)  

 // returns: none  
 Promise.join(promises)  
 // Creates a new promise that completes when all  
 // joined promises have completed  
 // promises: Parameter array of other promises  
 // returns: a new Promise  
 Promise.make(value)  
 // Makes a promise on a value. If the value is a promise it   
 // is returned. If the value is not a promise an immediate  
 // promise is returned  
 // value: an Object that may or may not be a promise  
 // returns: a Promise for the value  
 Promise.broken(exception)  
 // Makes a promise that is immediately broken  
 // exception: The error for the promise  
 // returns: a broken Promise for the exception  
 Promise.immediate(value)  
 // Makes a promise that is immediately fulfilled  
 // value: The value for the promise  
 // returns: a fulfilled Promise for the value  
 Promise.fetch(url, method, username, password, headers, query, body)   
 // Tamamlanmış bir XMLHttpRequest kaynağı için Promise objesi oluşturur
 Promise.json(url, method, username, password, headers, query, body)   
 // XMLHttpRequestden dönen parse edilmiş sonuç için promise oluşturma
 Promise.jsonp(url, query, callbackArg)  
 // jsonp kullanarak json isteği atmak için  

     Aşağıdaki linkler de bu konuda faydalı olabilir:
http://msdn.microsoft.com/en-us/library/windows/apps/hh700339.aspx
http://www.codefoster.com/post/2012/06/22/Using-Promises
http://code.msdn.microsoft.com/windowsapps/Promise-e1571015
     Haftaya Windows 8 JavaScript uygulamalarında veri bağlama işlemlerine değineceğiz. Görüşmek üzere..
Referanslar:
http://blogs.msdn.com/b/ie/archive/2011/09/11/asynchronous-programming-in-javascript-with-promises.aspx

1 yorum:

  1. Asenkron programlama diğer programlama dillerinde bu kadar basit değil ;)

    YanıtlaSil