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 相关文章推荐
jQuery 1.0.2
Oct 11 Javascript
学习jquery之一
Apr 27 Javascript
jQuery get和post 方法传值注意事项
Nov 03 Javascript
jquery中JSON的解析方式
Mar 16 Javascript
JS实现按比例缩放图片的方法(附C#版代码)
Dec 08 Javascript
ArtEditor富文本编辑器增加表单提交功能
Apr 18 Javascript
Node.js与Sails redis组件的使用教程
Feb 14 Javascript
js控制一个按钮是否可点击(可使用)disabled的实例
Feb 14 Javascript
JS实现图片预览的两种方式
Jun 27 Javascript
vue实现虚拟列表功能的代码
Jul 28 Javascript
CentOS 8.2服务器上安装最新版Node.js的方法
Dec 16 Javascript
vue+element ui实现锚点定位
Jun 29 Vue.js
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
PHP5.0对象模型探索之抽象方法和抽象类
2006/09/05 PHP
php 模拟 asp.net webFrom 按钮提交事件的思路及代码
2013/12/02 PHP
Symfony2在Nginx下的配置方法图文教程
2016/02/04 PHP
PHP合并两个或多个数组的方法
2019/01/20 PHP
PHP使用HTML5 FileApi实现Ajax上传文件功能示例
2019/07/01 PHP
PHP defined()函数的使用图文详解
2019/07/20 PHP
JXTree对象,读取外部xml文件数据,生成树的函数
2007/04/02 Javascript
IE iframe的onload方法分析小结
2010/01/07 Javascript
JS的Document属性和方法小结
2013/09/17 Javascript
javascript实现省市区三级联动下拉框菜单
2015/11/17 Javascript
利用Vue.js框架实现火车票查询系统(附源码)
2017/02/27 Javascript
关于vue单文件中引用路径的处理方法
2018/01/08 Javascript
Nodejs把接收图片base64格式保存为文件存储到服务器上
2018/09/26 NodeJs
微信小程序实现多选功能
2018/11/04 Javascript
vue安装遇到的5个报错及解决方法
2019/06/12 Javascript
如何在微信小程序中存setStorage
2019/12/13 Javascript
[14:56]教你分分钟做大人:巫医
2014/10/30 DOTA
Python写的服务监控程序实例
2015/01/31 Python
Python中的super()方法使用简介
2015/08/14 Python
Python对象转JSON字符串的方法
2016/04/27 Python
python中利用zfill方法自动给数字前面补0
2018/04/10 Python
ipython和python区别详解
2019/06/26 Python
python 截取XML中bndbox的坐标中的图像,另存为jpg的实例
2020/03/10 Python
Python控制台实现交互式环境执行
2020/06/09 Python
实例教程 一款纯css3实现的数字统计游戏
2014/11/10 HTML / CSS
HTML5新标签兼容——> 的两种方法
2018/09/12 HTML / CSS
NBA欧洲商店(法国):NBA Europe Store FR
2016/10/19 全球购物
百联网上商城:i百联
2017/01/28 全球购物
阿里巴巴英国:Alibaba英国
2019/12/11 全球购物
求职信的最佳写作思路
2014/02/01 职场文书
2014婚礼司仪主持词
2014/03/14 职场文书
酒后驾车标语
2014/06/30 职场文书
小学教师读书活动总结
2014/07/08 职场文书
个人查摆剖析材料
2014/10/04 职场文书
基层工作经验证明样本
2014/11/16 职场文书
爱国主题班会教案
2015/08/14 职场文书