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 相关文章推荐
复制本贴标题和地址的js代码
Jul 01 Javascript
jquery下利用jsonp跨域访问实现方法
Jul 29 Javascript
利用Node.js制作爬取大众点评的爬虫
Sep 22 Javascript
遍历json 对象的属性并且动态添加属性的实现
Dec 02 Javascript
bootstrap 表单验证使用方法
Jan 11 Javascript
值得分享和收藏的xmlplus组件学习教程
May 05 Javascript
JS获取字符对应的ASCII码实例
Sep 10 Javascript
ES6下子组件调用父组件的方法(推荐)
Feb 23 Javascript
在ES5与ES6环境下处理函数默认参数的实现方法
May 13 Javascript
JavaScript设计模式之单例模式原理与用法实例分析
Jul 26 Javascript
微信小程序点击列表跳转到对应详情页过程解析
Sep 26 Javascript
vue 解决provide和inject响应的问题
Nov 12 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
Flash空降上海 化身大魔王接受挑战
2020/03/02 星际争霸
PHP里的中文变量说明
2011/07/23 PHP
简单实现PHP留言板功能
2016/12/21 PHP
php 三大特点:封装,继承,多态
2017/02/19 PHP
PHP实现Session入库/存入redis的方法
2017/05/04 PHP
JavaScript 快捷键设置实现代码
2009/03/13 Javascript
JavaScript 全角转半角部分
2009/10/28 Javascript
JavaScript实现的圆形浮动标签云效果实例
2015/08/06 Javascript
基于jQuery实现仿百度首页换肤背景图片切换代码
2015/08/25 Javascript
Webpack实现按需打包Lodash的几种方法详解
2017/05/08 Javascript
详解关于Vue版本不匹配问题(Vue packages version mismatch)
2018/09/17 Javascript
vxe-table vue table 表格组件功能
2019/05/26 Javascript
微信小程序基于高德地图API实现天气组件(动态效果)
2020/10/22 Javascript
[01:23:24]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第三场 2月7日
2021/03/11 DOTA
Python脚本在Appium库上对移动应用实现自动化测试
2015/04/17 Python
使用Python读取安卓手机的屏幕分辨率方法
2018/03/31 Python
Python+OpenCV目标跟踪实现基本的运动检测
2018/07/10 Python
对TensorFlow的assign赋值用法详解
2018/07/30 Python
树莓派使用USB摄像头和motion实现监控
2019/06/22 Python
python opencv捕获摄像头并显示内容的实现
2019/07/11 Python
使用Python自动生成HTML的方法示例
2019/08/06 Python
django执行数据库查询之后实现返回的结果集转json
2020/03/31 Python
纯CSS和jQuery实现的在页面顶部显示的进度条效果2例(仿手机浏览器进度条效果)
2014/04/16 HTML / CSS
让IE支持CSS3的不完全兼容方案
2014/09/19 HTML / CSS
日本高端护肤品牌:Tatcha
2016/08/29 全球购物
美国半成品食材配送服务商:Home Chef
2018/01/25 全球购物
static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
2015/02/22 面试题
承办会议欢迎词
2014/01/17 职场文书
上级检查欢迎词
2014/01/18 职场文书
体育课课后反思
2014/04/24 职场文书
全国税务系统先进集体事迹材料
2014/05/19 职场文书
视光学专业自荐信
2014/06/24 职场文书
地理科学专业自荐信
2014/09/01 职场文书
建筑横幅标语
2014/10/09 职场文书
2015年招聘工作总结
2014/12/12 职场文书
六年级语文下册教学计划
2015/01/22 职场文书