1. 程式人生 > 其它 >JavaScript: Promise async await

JavaScript: Promise async await

 

  1. 使用Promise封裝ajax
    function ajax (url) {
      return new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest()
        xhr.onreadystatechange = function () {
          if (this.readyState === 4) {
            if (this.status === 200) {
              console.log('resolve')
              resolve(this.responseText)
            } 
    else { console.log('error',) reject(new Error('reject error')) } } } xhr.open('get', url) xhr.send() }) }
      <script>
        function send () {
          ajax('http://localhost:555/vanity')
            .then(data => { console.log(data); return ajax('http://localhost:555/vanity
    ') }, err => console.log(err)) .then(data => { console.log(data); return ajax('http://localhost:555/vanity') }, err => console.log(err)) .then(data => { console.log(data); return ajax('http://localhost:555/vanity') }, err => console.log(err)) .then(data => console.log(data), err => console.log(err)) }
    </script>

     

  2. Promise實現
    class MyPromise {
      status = 'pending'  // 初始狀態
      value = undefined
      reason = undefined
      onfulfilled = undefined
      onrejected = undefined
      constructor(executor) {
        console.log('constructor')
        executor(this.resolve, this.reject)
      }
    
      resolve = value => {
        console.log('resolve')
        if(this.status !== 'pending') return
        this.status = 'fulfilled'
        this.value = value
        this.onfulfilled && this.onfulfilled(this.value)
      }
    
      reject = reason => {
        console.log('reject')
        if(this.status !== 'pending') return
        this.status = 'rejected'
        this.reason = reason
        this.onrejected && this.onrejected(this.reason)
      }
    
      then(onfulfilled, onrejected) {
        console.log('call then')
        if(this.status === 'fulfilled') {
          console.log('then fulfilled')
          onfulfilled(this.value)
        } else if(this.status === 'rejected') {
          console.log('then reject')
          onrejected(this.reason)
        } else {  // 非同步回撥必定到此處
          console.log('then pending')
          this.onfulfilled = onfulfilled  // 為當前Promise物件繫結then的成功回撥
          this.onrejected = onrejected  // 為當前Promise物件繫結then的失敗回撥
        }
      }
    }

    fs.readFile

    import fs from 'fs'
    
    let pp = new MyPromise((resolve, reject) => {
      fs.readFile('./a.txt', 'utf8', (err, data) => {
        if(err) {  // readFile非同步回撥進入EventLoop, 必定後於then執行
          reject(err)
        } else {
          resolve(data)
        }
      })
    })
    // 繫結成功和失敗的執行函式
    pp.then(data => console.log(data), err => console.log(err))

    new Date().getTime() 模擬

    let promise = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        const timestamp = new Date().getTime()
        if(timestamp % 2) {
          resolve(`odd ${timestamp}`)
        } else {
          reject(`even ${timestamp}`)
        }
      },1000)
    })
    
    promise.then(value => {
      console.log('success', value)
    }, err => {
      console.log('fail', err)
    })