Sözler Nasıl Çalışır? – JSMifest

Sözler Nasıl Çalışır?  – JSMifest

Sözler Nasıl Çalışır?

Vaatler aslında gerçek hayattaki durumlara çok benzer. Gerçek hayatta herhangi bir vaat durumunu kelimenin tam anlamıyla düşünebilir ve doğrudan koda dönüştürebilirsiniz.

O halde bir örnek nedir?

Kelly adında en iyi bir arkadaşınız olduğunu ve bölgede açılan bu yeni kahve dükkanına göz atması için onu davet etmek istediğinizi hayal edin.

Ona mesaj atmaya karar verdin ve şimdi bir cevap bekliyorsun. o da olacak kabul davetiniz, yoksa o yapacak reddetmek BT. Kabul ederse, sen ve Kelly birlikte takılabileceğiniz bir tarihe karar verebilirsiniz. Aksi takdirde, reddederse birlikte kafeye gitmeyeceksiniz. (Daveti tekrar başlatmaya karar vermezseniz ve belki bir dahaki sefere kabul eder!)

Bu, bir JavaScript sözünün 3 durumunu temsil eden bir örnekti:

  1. Beklemede – Kabul edene (çözene) veya reddedene kadar bekliyorsunuz
  2. Yerine Getirildi – Yeni kahve dükkanını sizinle birlikte gezmeyi kabul etti
  3. Reddedildi – Davetinize hayır diyecek

Nasıl Söz Oluştururum?

Şimdi daha JavaScript-y bir şekilde anlamak için, bu benzetmeyi JavaScript koduna dönüştürelim:

Burada Kelly ile etkileşime geçmek için API yöntemleri sağlayan bir yazılım geliştirme kitimiz var.

import kellyApi from 'kelly-sdk'

const makeKelly = ({ mood }) => {
  const _kelly = {}
  if (mood) _kelly.mood = mood

  return {
    ask(question) {
      return new Promise((resolve, reject) => {
        if (question) {
          const answer = kellyApi.askQuestion(question)
          resolve(answer)
        } else reject('No question asked')
      })
    },
  }
}

const kelly = makeKelly({ mood: 'happy' })

Fonksiyonun içinde, metodu içeren bir nesne döndürürüz. ask, ki bu bir Sözdür. Yeni bir Promise örneği döndürür ve sağladığı argümanlar resolveve reject.

İşlev başarılıysa, araması gerekir çözmek. Değilse, aramalı reddetmek. Arayana iletilecek argümanları argüman olarak kabul eder.

Sözleri Nasıl Kullanırım?

Artık bir söz oluşturduğumuza ve artık kullanılabilir olduğuna göre deneyelim:

const askKelly = (question) => {
  return new Promise((resolve, reject) => {
    kelly
    .ask(question)
    .then((answer) => {
      
      
      resolve(answer)
    })
    .catch((error) => {
      
      reject(error)
    })
  })
}

askKelly(
  'Hi kelly, there is a new coffee shop that opened. Would you like to go check it out with me?',
)
.then((result) => console.log(result))
.catch((error) => console.error(error))

Söz Zincirleme

Sözlerle ilgili güzel bir şey, zincirlenebilmeleridir. Diyelim ki Kelly daveti kabul etti ve şimdi ikinizin de özgür olduğu bir tarih belirlemeye devam ediyorsunuz.

kullanacağız an gelecekteki bir tarih için sorgulamak için kitaplık.

Yürütmeye devam etmek için ayrı bir Söz/işlev yazmak yerine, önceki Sözü geri döndürerek Sözü zincirleyebilirsiniz:

import moment from 'moment'

const makePlan = (options) => {
  return new Promise((resolve) => {
    resolve({
      date: '',
      ...options,
    })
  })
}
const chooseDate = (isoString) => {
  return new Promise((resolve) => {
    resolve(moment(isoString).format('MMMM Do, YYYY'))
  })
}
let plan
const askKelly = (question) => {
  return new Promise((resolve, reject) => {
    kelly
    .ask(question)
     .then((answer) => {
      
      return makePlan({ messages: [] })
    })
        .then((newPlan) => {
      plan = newPlan
      plan.messages.push({ me: question })
      plan.messages.push({ kelly: answer })
      
      const futureDateAsISO = moment()
        .add(14, 'days')
        .toISOString()
      return chooseDate(futureDateAsISO)
    })
    .then((readableDate) => {
      console.log(readableDate)
      
      
      return kelly.ask(`Great! How does ${readableDate} sound?`)
    })
    .then((answer) => {
      
      console.log(answer)
      resolve(answer)
    })
    .catch((error) => {
      
      reject(error)
    })
  })
}

askKelly(
  'Hi kelly, there is a new coffee shop that opened. Would you like to go check it out with me?',
)
.then((result) => console.log(result))
.catch((error) => console.error(error))

Güzel görünmüyor mu? Söz zincirlemenin yararı, kodunuzun yalnızca eşzamanlı görünmesi değil, aynı zamanda okunması ve hata ayıklamasının daha kolay olmasıdır!

Sözlerin eşzamansız doğası ve ne kadar zor olabileceği göz önüne alındığında, bu JavaScript dilinde uygulanan güçlü bir özelliktir ve geri arama cehennemi.

ES7 – Zaman Uyumsuz Bekleniyor

ES7’de tanıtılan güçlü bir özellik async/await’tir. Bu işlevler, senkronize görünmesini sağlarken asenkron kod yazmanıza izin verir. Normalde, insanlar hataları düzgün bir şekilde yakalamak için bu fonksiyon bloklarını bir dene/yakala ile sararlar.

İşte async/await kullanarak önceki örnek kodumuzun yeniden yazılmış bir örneği:

import moment from 'moment'

const makePlan = (options) => {
  return new Promise((resolve) => {
    resolve({
      date: '',
      ...options,
    })
  })
}
const chooseDate = (isoString) => {
  return new Promise((resolve) => {
    resolve(moment(isoString).format('MMMM Do, YYYY'))
  })
}
const askKelly = async (question) => {
  try {
    const answer = await kelly.ask(question)
    const plan = await makePlan({ messages: [] })
    plan.messages.push({ me: question })
    plan.messages.push({ kelly: answer })
    
    const futureDateAsISO = moment()
      .add(14, 'days')
      .toISOString()
    const readableDate = await chooseDate(futureDateAsISO)
    console.log(readableDate)
    
    
    const nextAnswer = await kelly.ask(`Great! How does ${readableDate} sound?`)
    console.log(nextAnswer)
  } catch (error) {
    
  }
}

askKelly(
  'Hi kelly, there is a new coffee shop that opened. Would you like to go check it out with me?',
)
.then((result) => console.log(result))
.catch((error) => console.error(error))

Çok daha kısa ve düzgün, değil mi?

Sözlere Neden İhtiyaç Duyarız ve Bunları Ne Zaman Kullanırız?

Öyleyse neden vaatlere ihtiyacımız var? Hangi sorunları çözüyorlar? Buna dalmadan önce, geçmişe bir adım atalım ve buna neden ihtiyaç duyulduğunu görelim:

Normal İşlevler ve Zaman Uyumsuz İşlevler

Veri almak için bir API’ye bir HTTP isteği gerçekleştirmeniz gerektiğini düşünün. Bu eşzamansız bir çağrıdır, dolayısıyla verilerin dönmesi için biraz beklememiz gerekir.

Söz vermeseydik, verileri beklemek için bir geri arama kalıbı kullanmamız gerekirdi:

const retrieveDataFromAPI = function(url, callback) {
  const httpRequest = new XMLHttpRequest()
  httpRequest.onreadystatechange = function() {
    if (httpRequest.readyState == 4 && httpRequest.status == 200) {
      
      if (typeof callback === 'function') {
        callback(httpRequest.response)
      }
    }
  }
  httpRequest.open('GET', url, true)
  httpRequest.responseType = 'json'
  httpRequest.send()
}

retrieveDataFromAPI('https://someapi.com/v1/someendpoint', function(
  responseData,
) {
  console.log(responseData)
})

Hiç birşey yok yanlış bu tür bir kod stili ile ve geri arama modeli, bugün herhangi bir uygulamada vaat edilen kadar etkilidir.

Bununla birlikte, bir geliştirici olarak, mükemmel bir kod mimarisi yazmak için gereksiz zaman harcamadan (ve kod performansını bozmadan) kodu daha okunaklı hale getiren daha kolay sözdizimi kullanarak hayatımı kolaylaştırmayı ve zamandan tasarruf etmeyi seviyorum.

Bu şuna atıfta bulunuyor: geri arama cehennemi geri arama doğasında sorun. Geri arama cehennemi olduğunda, kodunuz şöyle görünmeye başlar saçmalık. İnsanlar kodunuzu okumaya çalışırken kendi saçlarını çektikleri için hatalar oluşmaya başlar.

Bir önceki çağrının yanıt sonucuna göre aynı api’yi farklı parametrelerle çağırmak istediğimizi varsayalım.

İşte böyle görünebilir:

const data = {
    doctors: [],
}

retrieveDataFromAPI('https://someapi.com/v1/someendpoint', function(
  responseData,
) {
  console.log(responseData)
  if (responseData.result) {
      if responseData.result.doctors.length > 0) {
          const doctorIds = responseData.result.doctors.map((doctor) => doctor.id)
          if (doctorIds.length) {
              data.doctors.push(...doctorIds)
          }
          
          retrieveDataFromAPI(`https://someapi.com/v1/someotherendpoint?ids=${doctorIds}&limit=300`, function(moreData) {
              if (moreData.result) {
                  if (moreData.result.data) {
                      console.log(moreData.result.data)
                      retrieveDataFromAPI(`https://someapi.com/v1/thirdendpoint?limit=300`, function(additionalData) {
                          console.log(additionalData)
                      })
                  }
              }
          })
      }
  }
})

Geri Çağırma Cehenneminden Kaçınmak–Vaat Cennetine Adım Atmak

Vaatlerle, daha az hantal hale gelir ve kodun okunması çok daha kolay hale gelir:

const retrieveDataFromAPI = function(url) {
  return new Promise((resolve, reject) => {
    const httpRequest = new XMLHttpRequest()
    httpRequest.onreadystatechange = function() {
      if (httpRequest.readyState == 4 && httpRequest.status == 200) {
        
        if (typeof callback === 'function') {
          resolve(httpRequest.response)
        }
      } else if (httpRequest.status > 400) {
        reject(httpRequest.statusText)
      }
    }
    httpRequest.open('GET', url, true)
    httpRequest.responseType = 'json'
    httpRequest.send()
  })
}

retrieveDataFromAPI('https://someapi.com/v1/someendpoint')
  .then((responseData) => {
    if (responseData.result) {
      if (responseData.result.doctors.length > 0) {
        const doctorIds = responseData.result.doctors.map((doctor) => doctor.id)
        if (doctorIds.length) {
          data.doctors.push(...doctorIds)
        }
        
        return retrieveDataFromAPI(
          `https://someapi.com/v1/someotherendpoint?ids=${doctorIds}&limit=300`,
        )
      }
    }
  })
  .then((moreData) => {
    if (moreData.result) {
      if (moreData.result.data) {
        console.log(moreData.result.data)
        return retrieveDataFromAPI(
          `https://someapi.com/v1/thirdendpoint?limit=300`,
        )
      }
    }
  })
  .then((additionalData) => {
    console.log(additionalData)
  })

Sözlerle geri aramayı düzleştiririz .then. Bir bakıma yuvalama azaldığı için daha temiz görünüyor. Tabii ki, ES7 ile async sözdizimi, daha okunabilir bir yaklaşımla örneğimizi daha da optimize edebiliriz. Dene!

Özet

Sözler, flip telefonlara kıyasla androidler gibidir. Hayatınızı kolaylaştırır ve kod, JavaScript geliştiricileri tarafından günlük iş akışlarında geniş çapta benimsenmiştir. Geri arama yazıyorsanız ve hiç söz yazmadıysanız, Sözler’e aşina olmanızı ve sizin için işe yarayıp yaramadığını görmenizi öneririm 🙂

Mutlu Kodlama!

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.