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


Posted in Javascript onMay 17, 2019

异步编程

众所周知 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

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 函数会返回一个遍历器对象,使用该对象的 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

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

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

Javascript 相关文章推荐
用倒置滤镜把div倒置,再把table倒置。
Jul 31 Javascript
基于Jquery的淡入淡出的特效基础练习
Dec 13 Javascript
jQuery实现动画效果的实例代码
May 07 Javascript
简单的邮箱登陆的提示效果类似于yahoo邮箱
Feb 26 Javascript
js判断浏览器版本以及浏览器内核的方法
Jan 20 Javascript
基于JavaScript实现百叶窗动画效果不只单纯flas可以实现
Feb 29 Javascript
js无提示关闭浏览器窗口的两种方法分析
Nov 06 Javascript
原生javascript上传图片带进度条【实例分享】
Apr 06 Javascript
clipboard在vue中的使用的方法示例
Oct 19 Javascript
vue+element树组件 实现树懒加载的过程详解
Oct 21 Javascript
JS合并两个数组的3种方法详解
Oct 24 Javascript
js实现盒子拖拽动画效果
Aug 09 Javascript
150行代码带你实现微信小程序中的数据侦听
May 17 #Javascript
angular4应用中输入的最小值和最大值的方法
May 17 #Javascript
jQuery实现的点击显示隐藏下拉菜单功能完整示例
May 17 #jQuery
详解 微信小程序开发框架(MINA)
May 17 #Javascript
Vue模板语法中数据绑定的实例代码
May 17 #Javascript
jQuery控制input只能输入数字和两位小数的方法
May 16 #jQuery
微信小程序云开发详细教程
May 16 #Javascript
You might like
PHP 高手之路(一)
2006/10/09 PHP
flash用php连接数据库的代码
2011/04/21 PHP
php实现用于删除整个目录的递归函数
2015/03/16 PHP
详解PHP的Yii框架中日志的相关配置及使用
2015/12/08 PHP
让Laravel API永远返回JSON格式响应的方法示例
2018/09/05 PHP
JavaScript中令你抓狂的魔术变量
2006/11/30 Javascript
统一接口:为FireFox添加IE的方法和属性的js代码
2007/03/25 Javascript
JQuery1.6 使用方法三
2011/11/23 Javascript
js创建元素(节点)示例
2014/01/02 Javascript
原生javascript实现简单的datagrid数据表格
2015/01/02 Javascript
分享几种比较简单实用的JavaScript tabel切换
2015/12/31 Javascript
BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)
2016/08/17 Javascript
JS获取html元素的标记名实现方法
2016/10/08 Javascript
基于Javascript实现的不重复ID的生成器
2016/12/25 Javascript
JavaScript评论点赞功能的实现方法
2017/03/13 Javascript
快速使用node.js进行web开发详解
2017/04/26 Javascript
AngularJS 的$timeout服务示例代码
2017/09/21 Javascript
Vue登录注册并保持登录状态的方法
2018/08/17 Javascript
axios使用拦截器统一处理所有的http请求的方法
2018/11/02 Javascript
微信小程序遍历Echarts图表实现多个饼图
2019/04/25 Javascript
Vue中axios的封装(报错、鉴权、跳转、拦截、提示)
2019/08/20 Javascript
JS实现前端路由功能示例【原生路由】
2020/05/29 Javascript
JavaScript实现与web通信的方法详解
2020/08/07 Javascript
pandas修改DataFrame列名的实现方法
2019/02/22 Python
从0开始的Python学习014面向对象编程(推荐)
2019/04/02 Python
python实现五子棋游戏
2019/06/18 Python
Django框架创建mysql连接与使用示例
2019/07/29 Python
python GUI库图形界面开发之PyQt5表格控件QTableView详细使用方法与实例
2020/03/01 Python
Python通过yagmail实现发送邮件代码解析
2020/10/27 Python
惠普香港官方商店:HP香港
2019/04/30 全球购物
自荐信怎么写好
2013/11/11 职场文书
学期自我评价
2014/01/27 职场文书
门前三包责任书
2014/04/15 职场文书
党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
大学生奖学金获奖感言(范文)
2019/08/15 职场文书
Windows11里微软已经将驱动程序安装位置A盘删除
2021/11/21 数码科技