0
点赞
收藏
分享

微信扫一扫

javaScript异步编程

钟罗敏 2022-02-21 阅读 72

概述

  • 同步与异步的差异
  • 事件循环与消息队列 ,即如何实现异步模式
  • 异步编程的方式
  • Promise 异步方案、宏任务/微任务
  • Generator异步方案、Async/Await语法糖

同步模式

  • 逐行执行
  • 阻塞

异步模式

  • 不会等待任务是否执行完成,立即执行下个任务
  • 后续逻辑通过回调函数定义
  • 代码混乱

异步分析

同步代码按文档顺序执行,碰见异步代码,先压入调用栈,之后直接弹出到异步api环境中,继续执行同步代码,在执行同步代码的同时,事件循环一直会等待消息对列中的异步代码完成,完成后事件循环压入到调用栈中进行执行。

异步编程的回调函数

可以理解想要做的一件事情,并不知道所要依赖的事情什么时候完成。交给依赖任务的执行者,当依赖任务执行完成,执行想要做的事情。

Promise编程

基本用法

// Promise构造函数接收一个函数作为参数,作为参数的函数有两个参数
	// resolve参数的类型是一个函数,将对象的状态修改为成功
		// resolve函数的参数,是异步任务的操作成功的结果
	// reject参数的类型是一个函数,将对象的状态修改为失败
		// reject函数的参数,是异步任务失败的原因
const promise = new Promise(function(resolve,reject){
    resolve(100)
    
    // reject(new Error('promise rejected'))
})
promise.then()

promise Ajax请求

// Promise 方式的 AJAX

function ajax (url) {
  return new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest()
    xhr.open('GET', url)
    // 设置响应类型
    xhr.responseType = 'json'
    xhr.onload = function () {
      if (this.status === 200) {
        resolve(this.response)
      } else {
        reject(new Error(this.statusText))
      }
    }
    xhr.send()
  })
}

ajax('/api/urls.json').then(function (res) {
  console.log(res)
}, function (error) {
  console.log(error)
})

Promise的链式调用

  • then方法会返回一个全新的Promise
  • then的resolve方法的返回是下个Promise resolve的参数值 reject同理
  • 后一个then方法就是在为上一Promise注册回调
  • 如果回调中返回的是promise,那么后面的then方法的回调会等待它的结果,为我们返回的Promise注册回调
ajax('/api/users.json')
  .then(function (value) {
    console.log(1111)
    return ajax('/api/urls.json')
  }) // => Promise
  .then(function (value) {
    console.log(2222)
    console.log(value)
    return ajax('/api/urls.json')
  }) // => Promise
  .then(function (value) {
    console.log(3333)
    return ajax('/api/urls.json')
  }) // => Promise
  .then(function (value) {
    console.log(4444)
    return 'foo'
  }) // => Promise
  .then(function (value) {
    console.log(5555)
    console.log(value)
  })

Promise异常

  • reject 就是对异常的处理

  • then方法中的rejec只能捕获上一个promise的异常

  • promise中的异常能够传递给下一个promise catch方法直接捕获异常

  • 在window对象上绑定unhandledrejection世界可以捕获那些没有被手动捕获的异常

// 不推荐使用,要手动捕获
window.addEventListener('unhandledrejection',event=>{
    const {reason,promise} = event
    console.log(reason,promise)
    // reason=>Promise 失败的原因
    // promise => 出现异常的promise
    event.preventDefault()
},false)
// node 中捕获异常
process.on('unhandledRejection',(reason,promise)=>{
    console.log(reason,promise)
})

promise静态方法

  • Promise.resolve(value)
    • 创建一个成功的方法,成功的回调函数的参数的值为value的值
    • 如果返回一个Promise,则会返回一个完全相等的Promise对象
  • Promise.rejected()

promise并行执行

Promise.all(array)将多个Promise对象合并成一个,如果所有的Promise都成功,这个新的promise也会成功,如果有一个失败这个promise就会失败,成功后resolve回调接收到一个数组,即所有promise返回的结果

  • 接收一个数组,数组中的每个元素都是一个Promise对象

promise.rece()子要有一个完成就会结束

promise执行顺序

  • 宏任务会重新排队
  • 微任务不会重新排队,优先执行,例:Promise、MutationObserver和node中的process.nextTick

Generator异步方案

Generator生成器函数

  • 执行函数是并不会立即调用函数,返回一个生成器对象

语法:

function * foo(){
    console.log('start')
   // yield 'foo'
    
    try{
        const res = yield 'foo'
        console.log(res)
    }catch(e){
        console.log(e)
    }
    // 可以捕获generator.throw()方法抛出的异常
}
const generator = foo() // 返回一个生成器对象
const result = generator.next() // 调用next()方法函数开始执行,返回一个对象
/*
	result 对象
	value yield返回的值
	done 表明generator是否执行完了
*/
generato.throw(new Error('Generator error'))
举报

相关推荐

0 条评论