JavaScript异步编程的六种方式总结

作者:闭包旅人时间:2026-10-23 07:23:37浏览:128

本文系统总结了JavaScript中处理异步编程的六种主流方式。从传统的回调函数和事件监听,到发布订阅模式,再到ES6引入的Promise、Generator以及ES7的async/await。通过具体代码示例对比各方案的优缺点,帮助开发者理解异步执行机制并选择合适方案。

JavaScript异步编程概述

异步编程

JavaScript 采用单线程模型,即仅有一个脚本执行完毕后,后续脚本方可启动,且脚本间无法并发执行。若某脚本执行耗时较长,后续脚本均需排队等待,从而导致整体程序执行效率降低。为实现类似多线程的并发处理能力,本文总结多种异步编程方案,供参考交流。

  1. 回调函数
  2. 事件监听
  3. 发布订阅模式
  4. Promise
  5. Generator (ES6)
  6. async (ES7)

传统异步解决方案:回调与事件

异步编程传统的解决方案:回调函数和事件监听

初始示例:假设有两个函数, f1 和 f2,f1 是一个需要一定时间的函数。


function f1() {
  setTimeout(function(){
    console.log('先执行 f1')
  },1000)
}
function f2() {
  console.log('再执行 f2')
}

回调函数

鉴于 f1 执行耗时,可将 f2 设定为 f1 的回调函数,从而将同步操作转化为异步操作。此举使 f1 不再阻塞程序运行,f2 亦无需被动等待,例如 JQuery 的 ajax 实现。

回调函数的demo:


function f1(f2){
  setTimeout(function(){
    console.log('先执行 f1')
  },1000)
  f2()
}
function f2() {
  console.log('再执行 f2')
}

效果如下:

 JavaScript异步编程概述

总结:回调函数易于实现、便于理解,但是多次回调会导致代码高度耦合

事件监听机制

事件监听

脚本的执行不取决代码的顺序,而取决于某一个事件是否发生。

事件监听的demo


$(document).ready(function(){
   console.log('DOM 已经 ready')
});

发布订阅模式

发布订阅模式

发布/订阅模式是利用一个消息中心,发布者发布一个消息给消息中心,订阅者从消息中心订阅该消息,。类似于 vue 的父子组件之间的传值。

发布订阅模式的 demo


//订阅done事件
$('#app').on('done',function(data){
  console.log(data)
})
//发布事件
$('#app').trigger('done,'haha')

现代异步方案:Promise与Generator

Promise

Promise 实际就是一个对象, 从它可以获得异步操作的消息,Promise 对象有三种状态,pending(进行中)、fulfilled(已成功)和rejected(已失败)。Promise 的状态一旦改变之后,就不会在发生任何变化,将回调函数变成了链式调用。

Promise 封装异步请求demo


export default function getMethods (url){
  return new Promise(function(resolve, reject){
    axios.get(url).then(res => {
      resolve(res)
    }).catch(err =>{
      reject(err)
    })
  })
}

getMethods('/api/xxx').then(res => {
  console.log(res)
}, err => {
  console.log(err)
})

Generator函数详解

Generator

Generator 函数是一个状态机,封装了多个内部状态。执行 Generator 函数会返回一个遍历器对象,使用该对象的 next() 方法,可以遍历 Generator 函数内部的每一个状态,直到 return 语句。

形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式, yield是暂停执行的标记。

next() 方法遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

Generator 的 demo


function *generatorDemo() {
 yield 'hello';
 yield 1 + 2;
 return 'ok';
}

var demo = generatorDemo()

demo.next()  // { value: 'hello', done: false } 
demo.next()  // { value: 3, done: false } 
demo.next()  // { value: 'ok', done: ture } 
demo.next()  // { value: undefined, done: ture } 

async/await语法

async

async函数返回的是一个 Promise 对象,可以使用 then 方法添加回调函数,async 函数内部 return 语句返回的值,会成为 then 方法回调函数的参数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

1.await命令后面返回的是 Promise 对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。

async 的 demo1


async function demo() {
 try {
  await new Promise(function (resolve, reject) {
   // something
  });
 } catch (err) {
  console.log(err);
 }
}

demo().then(data => {
  console.log(data) // 
})

参考文献

https://developers.google.com/web/fundamentals/primers/promises http://es6.ruanyifeng.com

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章