* ASENKRON PROGRAMLAMA *

Nurşin Keleş
5 min readFeb 26, 2021

--

Bu yazıda senkron-asenkron işlemler, JSON, ajax, callback, API, promise, fetch kavramlarına yer verirken ES7 ile birlikte asenkron programlamayı kolaylaştıran ve daha efektif kod yazmamızı sağlayan async ve await anahtar kelimelerini örneklerle açıklayacağım.

SENKRON VE ASENKRON İŞLEMLER

SENKRON: Kodlar yukarıdan aşağıya doğru sırayla işlenir ve bir satırdaki işlem bitmeden diğer satıra geçilmez.

ASENKRON: Uzun zaman alan veya farklı görevdeki işlemler aynı anda gerçekleştirilir.

process1();
process2();
proceess3();

Senkron işlemlerde , buradaki process2’nin çalışması process1'in bitmesine bağlıdır. Fakat asenkron işlemlerde process2'nin çalışmasına bağlı değildir. İşlemler birbirini beklemez.

Asenkron Yapılar

  • Ajax
  • Fetch
  • Node JS

Asenkron İşlemleri Nasıl Yönetebiliriz?

  • Callback(ES6 öncesi)
  • ES6 Promise
  • Async & Await

JSON (JAVASCRİPT OBJECT NOTATION) NEDİR?

JSON yapılı veri depolayan ve genellikle bir sunucu ve istemci arasında veri alışverişi için kullanılan bir formattır.

Temel amacı: XML’e göre daha küçük boyutlarda veri taşımaktır.

XML’e göre daha hızlı çalışmaktadır ve yazım şeklindeki farklılıklar nedeniyle daha az yer kaplamaktadır.

AJAX (ASYNCHRONOUS JAVASCRİPT AND XML) NEDİR?

XHR Objesi (XmlHttpRequest) üzerinden veri alma ve veri gönderimi, sayfa yenilenmeden asenkron veri alma, arka plandaki asenkron işlemler gerçekleşir. Bu obje internet tarayıcılarımızda bulunur. Bu veriler hem JSON hem de XML standartında gelebiliyor.

REST API (REPRESENTATİONAL STATE TRANSFER) NEDİR?

Web uygulamalarında temsili state transferi için kullandığımız bir mimaridir.

Rest yapısı stateless(state tutmayan) bir yapıdır.Http isteklerinde bulunuyoruz ve bizim yaptığımız istekler doğrultusunda Rest API genelde bize JSON objesi döndürür.Aynı zamanda bir çok dille beraber kullanabiliriz.

HTTP REQUEST

GET: EndPoint’e göre belli verileri alır.

POST: EndPoint’e göre belli veriyi gönderir.

PUT: EndPoint’e göre belli veriyi günceller.

DELETE: EndPoint’e göre belli veriyi siler.

CALLBACK FUNCTION

Fonksiyonları başka fonksiyonlara parametre olarak gönderebiliyoruz. Aynı zamanda asenkron işlemleri yönetebiliriz.

Bir fonksiyonu bir yerden veri geldiğinde çalıştırmak istersek o zaman bu fonksiyonu callback olarak göndermem gerekir.

function first(){ 
setTimeout(function() {
alert(1);
}, 500);
}
function second(){
alert(2);
}
first();
second();
// çıktı
// 2
// 1

Buradaki örnekte first() fonksiyonu ilk çalışmasına rağmen çıktı olarak daha sonra sonuç vermiştir. Bu javascriptin asenkron özelliğindendir. Bu gibi durumların önüne geçebilmek için callback kullanılmalıdır.

function first(callback){ 
setTimeout(function () {
alert(1);
callback()
}, 500);
}
function second(){
alert(2);
}
first(second);
// çıktı
// 1
// 2

CALLBACK HELL

Callback cehennemi, art arda bir çok callback kullandığımız zaman meydana gelir.
Bu şekilde yapılar hem programlarımızı okumayı zorlaştırırken hem de callback fonksiyonlarımızı yönetmeyi zorlaştırması sebepleriyle kullanışsız bir yöntemdir.

Bu problemin önüne geçebilmek için en iyi yöntem “promises” kullanmaktır.

PROMISE

Promise, callback’lerin sıkıntılı yönlerini düzeltmek amacıyla önerilmiş bir yapıdır.

Promise istenilen görevi yerine getirdiğinde değeri değişmez (immutable)

Sadece bir kere başarıya (resolved) ulaşır, veya başarısız (rejected) olur.

function getData(data){// promise objesi döndüren fonksiyon   return new Promise(function(resolve,reject){       setTimeout(function(){          if(typeof data === "string"){//olumlu
resolve(data);
}else{//olumsuz
reject(new Error("lütfen string bir değer girin"));
}
},3000);
});
}
getData("merhaba")
.then(response => console.log("gelen değer " + response)).catch(err => console.error(err));

Promise’leri new öneki ile tanımlıyoruz.

resolve ve reject durumlarda çağırılacak iki fonksiyon ile birlikte oluşturuyoruz.

Promise’leri bir değişkene atayabiliriz.

Promise beklenilen işlemi gerçekleştirdikten sonra yapılacak adımlar için .then() fonksiyonu çağırılır. İçerisindeki fonksiyonun parametresi resolve() ile gönderilen parametredir.

Eğer istek dahilinde reject() çağırıldığında veya öngörülemeyen bir hata sonucu promise başarısız olduğunda .then() fonksiyonu es geçilerek, .catch() içerisindeki fonksiyon çağırılır ve hatalı durumda yapılacak adımlar izlenir.

function addTwo(number){  return new Promise((resolve,reject) => {     setTimeout(function(){         if(typeof number === "number"){
resolve(number+2);
}else{
reject(new Error("lütfen number değer girin!!"));
}
},3000);
});
}
addTwo(5)
.then(response => { console.log(response);
return response+2;
}).then(response2 => console.log(response2)).catch(err => console.error(err));

Yukarıdaki örnekte görüldüğü üzere birden fazla then kullanılabilir(promise chain). Fakat birden fazla catch kullanılmaz.

FETCH

Fetch API, Ajax gibi veri alma, veri gönderme işlemlerinde kullanılan asenkron bir yapıdır.

//Text dosyasından verileri almafunction getTextFile() {
fetch("example.txt")
.then(response => response.text())
.then(data => console.log(data))
.catch(err =>console.log(err));
}
getTextFile();
//Local bir JSON dosyasından veri almafunction getJsonFile(){
fetch("example.json")
.then(response => response.json())
.then(data => console.log(data))
.catch(err =>console.log(err));
}
getJsonFile();
//Uzaktaki bir API'dan bilgimizi JSON objemizi alıyoruzfunction getExternalAPI(){
fetch("https://api.exchangeratesapi.io/latest")
.then(response => response.json())
.then(data => {
console.log(data.rates.TRY);
})
.catch(err =>console.log(err));
}
getExternalAPI();

ASYNC-AWAİT

Async ve await sayesinde kod daha okunaklı hale gelir. Bunun yanı sıra asenkron işlemlerin gerçekleşme sırasını takip etmek kolaylaşacak ve promise zincirleri için birçok .then() yazmak gerekmeyecek.

async anahtar kelimesi mutlaka promise döneceğini söyler.

await anahtar kelimesi ise bir promise’in resolve etmesini yani olumlu dönüş yapmasını bekler.

await sadece async olan fonksiyonlarda çalışır.

async function testData(data) {
let promise = new Promise((resolve,reject) => {
setTimeout(() => {
if(typeof data === "string") {
resolve(data);
}else{
reject(new Error("lütfen string bir değer girin"));
}
}, 5000);//programımız 5s resolve olmayı bekledi
});
const response = await promise;
return response;
}
testData("merhaba")
.then(data => console.log(data))
.catch(err => console.error(err));
//fetch fonksiyonu promise döner, bu promise'i await ile bekleyebiliriz.async function getCurrency(url){
const response = await fetch(url); //response object
//önce response objesi olarak bize döner, sonrasında JSON'a çevirme işlemini gerçekleştiririzconst data = await response.json(); //json object
return data;
}
getCurrency("https://api.exchangeratesapi.io/latest")
.then(response => console.log(response));

Async-Await Yapısıyla HTTP İstekleri

class Request {
async get(url){//get request
const response = await fetch(url); //response reject
const data = await response.json(); //json object
return data;
}
async post(url,data){
const response = await fetch(url,{
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-type': 'application/json; charset=UTF-8'
}
});//response object
const responseData = await response.json();
return responseData;
}
async put(url,data){
const response = await fetch(url,{
method: 'PUT',
body: JSON.stringify(data),
headers: {
'Content-type': 'application/json; charset=UTF-8',
}
});//response object
const dataput = await response.json();
return dataput;
}
async delete(url){
const response = await fetch("https://jsonplaceholder.typicode.com/albums/1",{
method: "DELETE"
});//response object
return "veri silme işlemi başarılı";
}
}
const request = new Request();
let albums;request.get("https://jsonplaceholder.typicode.com/albums")
.then(albums => console.log(albums))
.catch(err => console.log(err));
request.post("https://jsonplaceholder.typicode.com/albums",{userId:1,title:'Thriller'})
.then(newAlbum => console.log(newAlbum))
.catch(err =>console.log(err));
request.put("https://jsonplaceholder.typicode.com/albums/10",{userId:10,title:'Tarkan Karma'})
.then(album => console.log(album))
.catch(err =>console.log(err));

Bu bölümde oldukça önemli olan asenkron programlamaya değindim. Bununla beraber birçok geliştirici tarafından sıklıkla kullanılmakta olan promiselerin bize ne kadar kolaylık sağladığından bahsettim. Kod okunabilirliğine daha da çok yer vereceğim diğer yazılarda görüşmek dileğiyle..

“Every piece of knowledge must have a single, unambiguous, authoritative reprosentation in the system.”

--

--