JS异步代码

Promise

const promise = new Promise((resolve,reject)=>{
    // 立即执行
    // 成功返回resolve(),
    // 失败返回reject()
})

promise.then(()=>{
    console.log('成功调用')
}).catch(()=>{
    console.log('失败调用')
})

/*
resolve(promise)
如果resolve的值是Promise对象,那么当前的Promise的状态会由传入的Promise来决定

resolve(thenable)
resolve({
	name:'aa',
	then:function(resolve){
		console.log(111)
	}
})
*/

三个状态

  • pending: 初始状态
  • fulfilled:操作成功完成,执行resolve时,处于此状态,Promise已经被兑换
  • rejected: 操作失败,执行了reject,Promise被拒绝

一旦状态改变,将是不可逆的。

方法

  • then:
    • 返回一个Promise
    • return undefined,,
  • catch:
    • 执行时机,reject() / throw new Error('xxx')
  • finally
/*
类方法then/catch
*/
let studentList = []
let promise = Promise.resolve(studentList)  // 相当于 new Promise() 并且执行resolve
promise.then((res)=>{
    console.log(res)
})

all

/*
将多个Promise包裹在一起会形成一个新的Promise,当所有Promise 的状态都为fulfilled,新的Promise为fulfilled
当有一个Promise状态为reject时,新的Promise状态为reject,并且会将第一个reject的返回值作为参数
*/
let p1 = new Promise((resolve)=>{
    setTimeout(()=>{
        resolve('p1')
    },2000)
})
let p2 = new Promise((resolve)=>{
    setTimeout(()=>{
        resolve('p2')
    },1000)
})
let p3 = new Promise((resolve)=>{
    setTimeout(()=>{
        resolve('p3')
    },5000)
})

// 会在5s后返回结果
Promise.all([p1,p2,p3]).then((res)=>{
    console.log(res)   // ['p1', 'p2', 'p3']
})

let p4 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('p4')
    },5000)
})
let p5 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('p5')
    },1000)
})
let p6= new Promise((resolve)=>{
    setTimeout(()=>{
        resolve('p6')
    },5000)
})

// 会在5s后返回结果
Promise.all([p4,p5,p6]).then((res)=>{
    console.log(res)   // 
}).catch(err=>{
    console.log('err',err)
})

allSettled(ES11)

// 获取所有结果在then方法中
let p4 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('p4')
    },5000)
})
let p5 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('p5')
    },1000)
})
let p6= new Promise((resolve)=>{
    setTimeout(()=>{
        resolve('p6')
    },5000)
})

// 会在5s后返回结果 所有结果都返回在then中
Promise.allSettled([p4,p5,p6]).then((res)=>{
    //  [ {status: 'rejected', reason: 'p4'}, {status: 'rejected', reason: 'p5'},{status: 'fulfilled',value: 'p5'}]
    console.log(res)   
})

race

// 会等到一个Promise有结果,无论是成功或失败
let p4 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('p4')
    },5000)
})
let p5 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('p5')
    },1000)
})
let p6= new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('p6')
    },5000)
})

Promise.race([p4,p5,p6]).then(res=>{
    console.log(res)  
}).catch(err=>console.log('err',err))  // err p5

any

// 会等到一个Promise有结果,必须是fulfilled
let p4 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('p4')
    },5000)
})
let p5 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('p5')
    },1000)
})
let p6= new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('p6')
    },5000)
})

Promise.any([p4,p5,p6]).then(res=>{
    console.log(res)  // p4
}).catch(err=>{
    // 内部创建的错误信息,表示所有Promise都没有fulfilled
})

迭代器

帮助我们对某个数据结构进行遍历的对象

必须有一个next方法:

  • next
    • done: boolean
    • value:
const names = [1, 2, 3, 4]

function createInterator(arr) {
  let index = 0
  return  {
    next() {
      // done :boolean
      // value: 具体值/undefined
      if (index < names.length) {
        return { done: false, value: arr[index++] }
      } else {
        return { done: true, value: undefined }
      }
    }
  }
}
let obj = createInterator(names)
console.log(obj.next())
console.log(obj.next())
console.log(obj.next())
console.log(obj.next())
console.log(obj.next())
/*
{ done: false, value: 1 }
{ done: false, value: 2 }
{ done: false, value: 3 }
{ done: false, value: 4 }
{ done: true, value: undefined }
*/

迭代器对象

const infos = {
    names:[1, 2, 3, 4],
    [Symbol.iterator](){  // 必须使用 [Symbol.iterator](){}
        let index = 0
        return {
            next(){
                if (names.length > index) {
                    return {done:true}
                } else {
                    return {done:false,value:names[index++]}
                }
            }
        }
    }
}
const interator = infos[Symbol.iterator]()
console.log(interator.next())
console.log(interator.next())
console.log(interator.next())
console.log(interator.next())
console.log(interator.next())

for(let item of infos) {
  console.log(item)
}


// 优化
const infos = {
  names:[1, 2, 3, 4],
  [Symbol.iterator](){  // 必须使用 [Symbol.iterator](){}
      let index = 0
      let entries = Object.entries(this)
      return {
          next(){
              if (index < entries.length ) {
                return {done:false,value:entries[index++]}
              } else {
                return {done:true}
              }
          }
      }
  }
}

const interator = infos[Symbol.iterator]()
console.log(interator.next())
console.log(interator.next())


for(let item of infos) {
  let [key,value] = item
  console.log(key,value)
}
// 实现Iterator接口的自定义数组
class MyArray {
  constructor(...args){
      this.length = args.length
      for (let i=0;i<args.length;i++) {
          this[i] = args[i]
      }
  }
  // [Symbol.iterator](){
  //     let index = 0
  //     let that = this
  //     return {
  //         next(){
  //             return {
  //                 done:index < that.length,
  //                 value:that[index++]
  //             }
  //         },
  //     }
  // }
  *[Symbol.iterator](){   // 简写方式:生成器 + yield* 语法糖
    yield* this
  }
}

监听迭代中断

// return函数
class MyArray {
  constructor(...args){
      this.length = args.length
      for (let i=0;i<args.length;i++) {
          this[i] = args[i]
      }
  }
  [Symbol.iterator](){
      let index = 0
      let that = this
      return {
          next(){
              return {
                  done:index < that.length,
                  value:that[index++]
              }
          },
          return(){
              console.log('监听中断')
              return {done:true}
          }
      }
  }
}

生成器

函数控制,使用。更加灵活的控制函数什么时候继续执行,暂停执行
  • 在函数后加*
  • 通过yield控制函数执行流程
  • 生成器函数返回一个生成器
function* foo() {
  console.log(1111)
  let a = yield 'aaaa'   
  console.log(a)
  console.log(2222)
  yield 'bbbb'
  console.log(333)
  yield 'cccc'
  console.log(444)
  return 'dddd'   // return之后{done:true,value:undefined}
  yield 'gggg'
  console.log(6666)

}

let a = foo()
console.log(a.next())    // 执行第一个next函数时,运行的代码时console.log(1111) 'aaaa', 
console.log(a.next(88888))// 执行第二个next函数时,let a = 88888 console.log(a) console.log(2222) 'bbbb'

// 提前中断 return
console.log(a.return('aadd'))  

// 抛出异常 throw 
console.log(a.throw('aadd'))  

生成器代替迭代器

const names = [1, 2, 3, 4]
function* createArrayIterator(arr) {
  // for (let i = 0; i < arr.length; i++) {
  //   yield arr[i]
  // }
  yield* arr   // 语法糖,arr是一个可迭代对象, yield*会对对象进行依次,迭代
}

let iterator = createArrayIterator(names)

console.log(iterator.next())  // { value: 1, done: false }
console.log(iterator.next())  // { value: 2, done: false }
console.log(iterator.next())  // { value: 3, done: false }
console.log(iterator.next())  // { value: 4, done: false }
console.log(iterator.next())  // { value: undefined, done: true }

处理异步

function requestData(url){
    return new Promise((resolve,reject)=>{
        resolve(url)
    })
}

function* getData(){
    let res1 = yield requestData('h')
    let res2 = yield requestData(res1+'y')
    let res3 = yield requestData(res2+'f')
    console.log(res3)
}

let res = getData()
res.next().value.then(res1=>{
  res.next(res1).value.then(res2=>{
    res.next(res2).value.then(res3=>{
      console.log(res3)
    })
  })
})

// 自动执行生成器函数
function execGenfn(fn){
    const generator = fn()
    function exec(res){
        let result = generator.next(res)
        if (result.done) {
            return
        } 
        result.value.then(r=>{exec(r)})
    }
    exec()
}

async await

async function getData(){
    let res1 = await requestData('h')
    let res2 = await requestData(res1+'y')
    let res3 = await requestData(res2+'f')
    console.log(res3)
}

异步函数返回值

async function foo2(){
  // 1. 返回一个普通值
  // return 123  // Promise.resolve(123)
    
  // 2. 返回一个Promise
  // return new Promise((resolve,reject)=>{
  //   setTimeout(()=>{
  //     resolve(33)
  //   },1110)
  // })
    
  // 3. 返回一个thenable
  return {
    then(resolve,reject){
      resolve(33333)
    }
  }
}
foo2().then(res=>console.log(res))

异步函数中出现异常,会被Promise.reject()捕获

异常处理

function requestData(url){
    return new Promise((resolve,reject)=>{
        reject(url)
    })
}


async function getData(){
    try {
        const a = await requestData('ddd')
    } catch(error) {
        console.log('捕获异常代码:',error)
    }
}
posted @ 2023-01-06 13:18  转角90  阅读(52)  评论(0编辑  收藏  举报