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.validate使用攻略 第二部
Jul 01 Javascript
事件模型在各浏览器中存在差异
Oct 20 Javascript
初学Jquery插件制作 在SageCRM的查询屏幕隐藏部分行的功能
Dec 26 Javascript
基于JS实现简单的样式切换效果代码
Sep 04 Javascript
js实现C#的StringBuilder效果完整实例
Dec 22 Javascript
基于javascript实现tab选项卡切换特效调试笔记
Mar 30 Javascript
浅谈addEventListener和attachEvent的区别
Jul 14 Javascript
JS中位置与大小的获取方法
Nov 22 Javascript
vue-cli3.0 特性解读
Apr 22 Javascript
Vue.use源码学习小结
Jun 20 Javascript
Postman的下载及安装教程详解
Oct 16 Javascript
TypeScript基础入门教程之三重斜线指令详解
Oct 22 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重定向的三种方法分享
2012/02/22 PHP
解决PHP4.0 和 PHP5.0类构造函数的兼容问题
2013/08/01 PHP
PHP中soap的用法实例
2014/10/24 PHP
利用“多说”制作留言板、评论系统
2015/07/14 PHP
PHP7匿名类用法分析
2016/09/26 PHP
Thinkphp5.0框架使用模型Model的获取器、修改器、软删除数据操作示例
2019/10/11 PHP
用php实现分页效果的示例代码
2020/12/10 PHP
Jquery在IE7下无法使用 $.ajax解决方法
2009/11/11 Javascript
JavaScript 事件冒泡简介及应用
2010/01/11 Javascript
jQuery1.6 正式版发布并提供下载
2011/05/05 Javascript
jQuery中:focus选择器用法实例
2014/12/30 Javascript
简单介绍JavaScript数据类型之隐式类型转换
2015/12/28 Javascript
Jquery实现的简单轮播效果【附实例】
2016/04/19 Javascript
JS验证图片格式和大小并预览的简单实例
2016/10/11 Javascript
百度搜索框智能提示案例jsonp
2016/11/28 Javascript
微信小程序开发之大转盘 仿天猫超市抽奖实例
2016/12/08 Javascript
JavaScript中Promise的使用详解
2017/02/26 Javascript
AngularJS监听路由变化的方法
2017/03/07 Javascript
js使用i18n实现页面国际化的方法
2017/05/09 Javascript
vue实现鼠标移入移出事件代码实例
2019/03/27 Javascript
JavaScript实现轮播图特效
2020/04/10 Javascript
vue3.0生命周期的示例代码
2020/09/24 Javascript
[00:33]2016完美“圣”典风云人物:BurNIng宣传片
2016/12/10 DOTA
简述Python中的进程、线程、协程
2016/03/18 Python
python实现Decorator模式实例代码
2018/02/09 Python
python pandas库中DataFrame对行和列的操作实例讲解
2018/06/09 Python
使用python的pandas为你的股票绘制趋势图
2019/06/26 Python
win8.1安装Python 2.7版环境图文详解
2019/07/01 Python
python智联招聘爬虫并导入到excel代码实例
2019/09/09 Python
基于python实现模拟数据结构模型
2020/06/12 Python
python七种方法判断字符串是否包含子串
2020/08/18 Python
Python Tkinter实例——模拟掷骰子
2020/10/24 Python
为什么要做架构设计
2015/07/08 面试题
网络公司美工设计工作个人的自我评价
2013/11/03 职场文书
四年级语文教学反思
2014/02/05 职场文书
师范教师专业大学生职业生涯规划范文
2014/03/02 职场文书