JS异步代码

Posted 转角90

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)
    

以上是关于JS异步代码的主要内容,如果未能解决你的问题,请参考以下文章

ajax 的同步异步 js 的异步

script标签的async属性是用来异步加载,异步加载的作用是否同时下载,执行html代码和js代码

script标签的async属性是用来异步加载,异步加载的作用是否同时下载,执行html代码和js代码

Node.js插件编写-异步AsyncWorker的代码实现

Node.js插件编写-异步AsyncWorker的代码实现

Node.js插件编写-异步AsyncWorker的代码实现