promise asnyc await 和事件循环机制

123 阅读2分钟

promise

  • 参数为一个函数,这个函数的参数为 resolve, reject 执行promise参数函数内容后将正确结果用resolve返回 错误结果用reject返回 每个新的promise对象实例最初都是pending状态,当他执行了resolve后就将状态变成了fulfilled 当执行reject后状态就变成了rejected,这个状态只能正向改变,不可逆也不可变,不论是resolve还是reject都执行一次,且执行他们后这个参数函数停止执行后面的代码
let eg = new Promise((resolve, reject) => {
    if(Math.random()>0.5) {
        resolve('大于0.5')
    } else {
        reject('不大于0.5')
    }
    // 后面的代码不会执行了
})
  • 正确的结果由then 方法接受,错误的异常又catch接受
eg.then(res => {}).catch((err)=> {})

手动实现一个promise

    const PENDING = 'PENDING'
    const RESOLVED = 'fulfilled'
    const REJECTED = 'REJECTED'
    function _Promise(fn) {
        this.status = PENDING
        this.value = ''
        this.err = ''
        this.resolveStack = []
        this.rejectStack = []
        this.resolve = function (value) {
            this.status = RESOLVED
            this.value = value
            this.resolveStack.forEach(item => {
                item()
            });
        }
        this.reject = function (err) {
            this.status = REJECTED
            this.reason = err
            this.rejectStack.forEach(item => {
                item()
            });
        }
        try {
            fn(resolve,reject)
        } catch {
            reject(err)
        }
    })

.then .all

    Promise.protortype._then = function (onFulfilled, onRejected) {
        if (this.status == PENDING) {
            resolveStack.push(onFulfilled)
            rejectStack.push(onRejected)
        } else if (this.status == RESOLVED) {
            resolveStack.push(onFulfilled)
        } else if (this.status = REJECTED) {
            rejectStack.push(onRejected)
        }
    }
Promise.prototype._all = function(promiseArr) {
    return new Promise((resolve,reject) => {
      let results = []
      let count = 0
      promiseArr.forEach(item => {
          item.then(res => {
              results.push(res)
              count++
          }).catch(err => {
             reject(err)
          })
        })
      if(count == promiseArr.length)  {
          resolve(results)
      }
    })
}

async

async 函数 会返回一个promise 如果返回是一个值则用resolve包裹起来

  • async 附魔过的函数 会把return的结果包裹在promise中
 async function getSomething() {
        return "something";
    }
 const v1 = getSomething(); // 一个promise
 
 async function testAsync() {
        return Promise.resolve("hello async");
    }
 const v2 = testAsync();
  • await 只能使用在async函数内部,用于接收promise的返回值,如果promise返回错误 await将抛出错误,通过try/catch捕获
 function p1() {
        return new Promise((res,rej) => {
            console.log('p1')
            res('p1 resolved')
        })
    }
async function op1(){
    const a = await p1()
    console.log(a)
    return a
}

事件循环机制

  1. 同步任务遇到就执行,异步任务将放入异步队列栈中,当同步执行全部完成后,开始执行异步栈中的异步任务
  2. 异步任务内部也存在异步任务,依旧放入队列中,
  3. 异步任务分为宏任务和微任务,如果任务中的宏任务完成,就判断它是否存在微任务,如果有就执行微任务。上述任务全部完成后,再进行下一轮任务
  • 宏任务:script/setTimeout/setInterval/setImmediate/ I/O / UI Rendering
  • 微任务:process.nextTick()/Promise  
for(let macroTask of macroTaskQueue) {
    handMacroTask()
    for(let microTask of microTaskQueue) {
        handMicroTask()
    }
}
console.log('scriptstart')
setTimeout(() => {
     console.log('setTimeout1');
     Promise.resolve().then(() => {
          console.log('promise1')
    })
}, 0)
new Promise(resolve => {
    console.log('promise2');
    setTimeout(() => {
        console.log('setTimeout2');
        resolve();
    }, 0)
 })
 Promise.resolve().then(() => {
     console.log('promise3');
     setTimeout(() => {
          console.log('setTimeout3')
    },0)
 }).then(() => console.log('promise4'))
 console.log('scriptend');

scriptstart promise2 scriptend promise3 promise4 setTimeout1 promise1 setTimeout2 setTimeout3