专业的编程技术博客社区

网站首页 > 博客文章 正文

Js深度剖析~函数编程之异步编程(21/12/22)

baijin 2024-08-19 11:30:47 博客文章 6 ℃ 0 评论

概述

负责执行js代码的线程只有一个。

为了解决单线程带来的等待耗时问题,js将任务的执行模式分为两种,同步模式,异步模式。

内容概要:

  • 同步模式与异步编程
  • 事件循环与消息队列
  • 异步编程的几种方式
  • Promise异步方案,宏任务/微任务队列
  • Generator异步方案,Async/Await语法糖

同步模式

console.log('a')
console.log('b')
console.log('c')
console.log('d')
console.log('e')
// a,b,c,d,e

异步模式

不会等待这个任务的结束才开始下一个任务, js是单线程的,浏览器并不是单线程的。


回调函数

所有异步编程方案的根基。


Promise

一种更优的异步编程方案,避免回调地域问题。

概念:


基本使用:

const promise = new Promise(function (resolve, reject) {
  // 这里用于兑现承诺
  resolve(100) // 承诺达成

  // reject(new Error('promise rejected')) // 承诺失败
})

promise.then((result) => {
  console.log(result)
}, (error) => {
  console.log(error)
})

使用案例:

// 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/xxxxxx').then(function (res) {
  
}, function (err) {
  
})

常见误区:

避免嵌套使用 promise 可以使用 then方法的链式调用 。不然你又回到了回调地域的问题。

promise最大优势就是链式调用。

  • Promise对象的then方法 返回一个全新的Promise对象。
  • 后面的then方法就是在为上一个then返回的Promise注册回调
  • 前面then方法中回调函数的返回值会作为后面then方法回调的参数
  • 如果回调中返回的是Promise,那后面then方法的回调会等待它的结束。
ajax('/api/xxxxxx').then(function (res) {
  
}).then((res)=>{

}).then((res)=>{
  
}).then((res)=>{
  
}).then((res)=>{
  
})

异常处理:

静态方法:

Promise.resole() 成功

Promise.reject() 失败

并行执行:

// 并行执行
var pro = Promise.all([
  ajax('/api/xxxxxx'),
  ajax('/api/xxxxxx'),
  ajax('/api/xxxxxx'),
  ajax('/api/xxxxxx'),
  ajax('/api/xxxxxx')
])

pro.then(function (valuses) {
  console.log(valuses)
}).catch(function (error) {
  
})

Promise.race()

有其中一个执行了 那么这个就执行了。用于处理超时 异常更好的方案

Promise 执行时序:

// 微任务  a c b
console.log('a')

Promise.resolve().then(()=>{
  console.log('b')
})

console.log('c')

console.log('a')

setTimeout(() => {
  console.log('a1')
}, 0);

Promise.resolve().then(()=>{
  console.log('b')
})

console.log('c')
console.log('a')
// 宏任务
setTimeout(() => {
  console.log('a1')
}, 0);

Promise.resolve().then(()=>{
  console.log('b')
})

console.log('c')
// a c b a1

微任务 提高整体的响应能力

目前绝大多数异步调用都会作为宏任务执行。

Generator

//  Generator
function * foo() {
  console.log('a')

  try {
    const res = yield 'foo'
    console.log(res)
  } catch (error) {
    console.log(error)
  }
  
}

const generator = foo()
const result = generator.next()
console.log(result)

// generator.next('bar')

generator.throw(new Error('asdbsahsa'))

Async / Await 语法糖

async function main(params) {
  try {
    const a = await ajax('')
    const b = await ajax('')
    const c = await ajax('')
    const d = await ajax('')
    
  } catch (error) {
    
  }
}

const promise = main()

promise.then(()=>{
  console.log('aaa')
})

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表