Handwriting Promise (2)

Then realization is said to be difficult, the rest is simple

1. Implement catch

catch (failFun) {
    return this.then(undefined, failFun)
  }

catch also returns a promise, change it on the basis of then

2. Implementation of reject() and resolve()

Let me talk about usage first

Promise.reject(1) // 失败
Promise.resolve(2) // 成功
Promise.resolve(Promise.resolve(2)) // 成功
Promise.resolve(Promise.reject(2)) // 失败

Resolve can pass a value or a Promise object, reject can only pass a value, not a Promise object (the document says)

// 返回一个失败的Promise
  static reject = (value) => {
    return new Promise((resolve, reject) => {
      reject(value)
    })
  }

  // 成功的回调 返回一个Promise
  static resolve = (value) => {
    return new Promise((resolve, reject) => { // 如果是Promise 将结果执行返回
      if (value instanceof Promise) {
        value.then(resolve, reject)
      } else { // 如果是值 直接返回
        resolve(value)
      }
    })
  }

use:

window.Promise = new Promise
// let p = Promise.resolve(22)
// let p = Promise.resolve(Promise.resolve(2))
let p = Promise.resolve(Promise.reject(2))
p.then((res) => {
  console.log(res)
}, (error) => {
  console.log(error)
})

3. Implementation of all and race

all:

// Promise.all 接受一个promise数组
  // 如果其中有一个执行失败 则整个失败 全部成功才算成功
  // 成功的返回值 是一个是数组,数组中是每一个promise的成功返回值,顺序与接受一个promise数组顺序一一对应
  // 并返回一个新的Promise
  static all = (promiseArr) => {
    let values = [] // 接受成功的 Promise 的返回值
    let successCount = 0 // 成功个数计数
    return new Promise((resolve, reject) => {
      // 遍历执行每个promise
      promiseArr.forEach((p, index) => {
        p.then((res) => {
          successCount++
          // 如果数组中的promise执行成功,按照传入的数组的顺序来,把返回值放入数组中
          values[index] = res
          // 每一个都成功的判断
          if (successCount === promiseArr.length) {
            resolve(values)
          }
        }, (error) => {
          reject(error) // 有一个失败 返回的新的promise视为失败
        })
      })
    })
  }

experiment:


// 使用 实例化一个Promise 传入一个函数,这个函数有两个参数,每个参数也是一个函数
let p = new Promise((resolve, reject) => {
  setTimeout(() => {
    var random = Math.random()
    if (random > 0.5) {
      resolve(`success: ${random}`)
    } else {
      reject(`fail: ${random}`)
    }
  }, 1000)
})
window.Promise = new Promise
let p1 = Promise.resolve('success 1')
let p2 = Promise.resolve(Promise.resolve('success 2'))
Promise.all([p, p1, p2]).then((res) => {
  console.log(res)
}, (error) => {
  console.log(error)
})

No problem ok

race:

// race 也返回一个Promise, 谁先有结果就是谁
  static race = (promiseArr) => {
    return new Promise((resolve, reject) => {
      promiseArr.forEach((promiseItem) => {
        promiseItem.then((res) => {
          resolve(res)
        }, (error) => {
          reject(error)
        })
      })
    })
  }

Okay, the Promise source code is over

4. Macro task, micro task

Micro task: Promise

Macro task: timer

setTimeout(() => {
      console.log(1)
    }, 0)
    new Promise((resolve) => {
      console.log(2)
      resolve()
    }).then(() => {
      console.log(3)
    }).then(() => {
      console.log(4)
    })
    console.log(5)

Looking at the code from top to bottom, setTimeout is placed in the macro task queue. When it meets the Promise, it outputs 2 first. The new Pomise is synchronized, and then resolves, the Promise succeeds, and then down and then, put .then (console.log( 3)) Put into the micro-task queue, at this time console.log(3) has not been executed yet, and console.log(4) is not yet its turn, and then output 5, this time the synchronized code has been executed, first Look at the micro task, output 3, 3 is executed, the 4 following it is put into the micro task queue, and then execute 4, the micro task queue is empty, and the macro task queue 1 is executed

2 5 3 4 1

 

Guess you like

Origin blog.csdn.net/Luckyzhoufangbing/article/details/108688473