ES5 => Promise

Promise

  1. //Promise/A+ Promise status
  2. const STATUS = {
  3. PENDING: 'pending',
  4. FULFILLED: 'fulfilled',
  5. REJECTED: 'rejected'
  6. }
  7. class MyPromise{
  8. //constructor receive a cb
  9. constructor(excutor){
  10. this._status = STATUS.PENDING //Promise initalValue
  11. this._value = undefined //then cb
  12. this._resolveQueue = [] // resolve Trigger
  13. this._rejectQueue = [] // reject Trigger
  14. }
  15. // arrow function bind 'this'
  16. const resolve = value => {
  17. const run = () => {
  18. // Promise/A+
  19. if(this._status = STATUS.PENDING){
  20. this._status = STATUS.FULFILLED
  21. this._value = value // for then cb
  22. // resolve cb
  23. while(this._resolveQueue.length){
  24. const cb = this._resolveQueue.shift()
  25. cb(value)
  26. }
  27. }
  28. }
  29. //把resolve执行回调的操作封装成一个函数,放进setTimeout里,以实现promise异步调用的特性(规范上是微任务,这里是宏任务)
  30. setTimeout(run)
  31. }
  32. // same as resolve
  33. const reject = value => {
  34. const run = () => {
  35. if(this._status === STATUS.PENDING){
  36. this._status = STATUS.REJECTED
  37. this._value = value
  38. while(this._rejectQueue.length){
  39. const cb = this._rejectQueue.shift()
  40. cb(value)
  41. }
  42. }
  43. }
  44. setTimeout(run)
  45. }
  46. excutor(resolve,reject)
  47. }

Promise => then

  1. //then in class
  2. function then(onFulfilled,onRejected){re
  3. //Promise A+
  4. typeof onFulfilled !== 'function' ? onFulfilled = value => value : null
  5. typeof onRejected !== 'function' ? onRejected = error => error : null
  6. //then return Promise Object
  7. return new MyPromise((resolve,reject) => {
  8. const resolveFn = value => {
  9. try{
  10. const x = onFulfilled(value)
  11. // 分类讨论返回值,如果是Promise,那么等待Promise状态变更,否则直接resolve
  12. x instanceof MyPromise ? x.then(resolve,reject) : resolve(x)
  13. }catch(e){
  14. reject(e)
  15. }
  16. }
  17. })
  18. }
  19. const rejectFn = error => {
  20. try {
  21. const x = onRejected(error)
  22. x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
  23. } catch (error) {
  24. reject(error)
  25. }
  26. }
  27. switch (this._status) {
  28. case STATUS.PENDING:
  29. this._resolveQueue.push(resolveFn)
  30. this._rejectQueue.push(rejectFn)
  31. break;
  32. case STATUS.FULFILLED:
  33. resolveFn(this._value)
  34. break;
  35. case STATUS.REJECTED:
  36. rejectFn(this._value)
  37. break;
  38. }
  39. })
  40. }
  41. catch (rejectFn) {
  42. return this.then(undefined, rejectFn)
  43. }

Promise finally

  1. // promise.finally方法
  2. finally(callback) {
  3. return this.then(value => MyPromise.resolve(callback()).then(() => value), error => {
  4. MyPromise.resolve(callback()).then(() => error)
  5. })
  6. }

Promise static resolve

  1. // 静态resolve方法
  2. static resolve(value) {
  3. return value instanceof MyPromise ? value : new MyPromise(resolve => resolve(value))
  4. }

Promise static reject

  1. // 静态reject方法
  2. static reject(error) {
  3. return new MyPromise((resolve, reject) => reject(error))
  4. }

Promise static all

  1. // 静态all方法
  2. static all(promiseArr) {
  3. let count = 0
  4. let result = []
  5. return new MyPromise((resolve, reject) => {
  6. if (!promiseArr.length) {
  7. return resolve(result)
  8. }
  9. promiseArr.forEach((p, i) => {
  10. MyPromise.resolve(p).then(value => {
  11. count++
  12. result[i] = value
  13. if (count === promiseArr.length) {
  14. resolve(result)
  15. }
  16. }, error => {
  17. reject(error)
  18. })
  19. })
  20. })
  21. }

Promise static race

  1. // 静态race方法
  2. static race(promiseArr) {
  3. return new MyPromise((resolve, reject) => {
  4. promiseArr.forEach(p => {
  5. MyPromise.resolve(p).then(value => {
  6. resolve(value)
  7. }, error => {
  8. reject(error)
  9. })
  10. })
  11. })
  12. }
  13. }

Ajax

Version 1.0

  1. let xhr = new XMLHttpRequest() // 实例化
  2. xhr.open('get','www.xxx.com')
  3. xhr.onreadystateChange = () => {
  4. if(xhr.readyState === 4){
  5. if(xhr.status >= 200 && xhr.status < 300){
  6. let string = request.responseText
  7. let object = JSON.parse(string)
  8. }
  9. }
  10. }
  11. request.send()

Promise

  1. function ajax(url) {
  2. const p = new Promise((resolve, reject) => {
  3. let xhr = new XMLHttpRequest()
  4. xhr.open('get', url)
  5. xhr.onreadystatechange = () => {
  6. if (xhr.readyState == 4) {
  7. if (xhr.status >= 200 && xhr.status <= 300) {
  8. resolve(JSON.parse(xhr.responseText))
  9. } else {
  10. reject('请求出错')
  11. }
  12. }
  13. }
  14. xhr.send() //发送http请求
  15. })
  16. return p
  17. }
  18. let url = '/data.json'
  19. ajax(url).then(res => console.log(res)).catch(reason => console.log(reason))