stephenLYZ / Promise-Implementation

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Promise/A+ 简单实现

参考promise/a+规范
Basic Javascript promise implementation attempt

const PENDING = Symbol()
const FULFILLED = Symbol()
const REJECTED = Symbol()

export default class Aromise {
  constructor(resolver) {
    if (typeof this !== 'object') {
      throw new Error('Promises must be constructed via new')
    }
    if (typeof resolver !== 'function') {
      throw new Error('resolver must be a function')
    }
    this.status = PENDING
    this.value = null
    this.handlers = []
    this.resolve = this.resolve.bind(this)
    this.reject = this.reject.bind(this)
    this.handle = this.handle.bind(this)
    resolver(this.resolve, this.reject)
  }

  reject(error) {
    this.status = REJECTED
    this.value = error
    this.handlers.forEach(this.handle)
    this.handlers = []
  }

  resolve(result) {
    try {
      let then  = typeof result.then == 'function' ? result.then : null
      if (then) {
        this.then.call(result, this.resolve, this.reject)
        return
      }
      this.status = FULFILLED
      this.value = result
      this.handlers.forEach(this.handle)
      this.handlers = []
    } catch (error) {
      this.reject(error) 
    }
  }

  handle({onFulfill, onReject}) {
    switch(this.status) {
      case FULFILLED:
        onFulfill && onFulfill(this.value)
        break
      case REJECTED:
        onReject && onReject(this.value)
        break
      case PENDING:
        this.handlers.push({onFulfill, onReject})
    }
  }

  then(onFulfilled, onRejected) {
    return new Aromise((resolve, reject) => {
      this.handle({
        onFulfill: (value) => {
          if (typeof onFulfilled === 'function') {
            try {
              resolve(onFulfilled(value))
            } catch (error) {
              reject(error)
            }
          } else {
            resolve(value)
          }
        }, 
        onReject: (error) => {
          if (typeof onRejected === 'function') {
            reject(onRejected(error))
          } else {
            reject(error)
          }
        }
     })
    })
  }
}

test

const Aromise = require('../lib/Aromise.js')

function sleep(second) {
  return new Aromise((resolve, reject) => {
    setTimeout(() => resolve(second), second * 1000);
  })
}

new Aromise((resolve, reject) => {
  resolve('hello')
}).then((val) => {
  console.log(val)
  return sleep(3)
}).then(() => {
  return 'world'
}).then((val) => {
  console.log(val)
  return sleep(2)
}).then(() => {
  console.log('end')
})

About


Languages

Language:JavaScript 100.0%