博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript异步流程控制的前世今生
阅读量:7167 次
发布时间:2019-06-29

本文共 2826 字,大约阅读时间需要 9 分钟。

javascript在设计之初.为了避免资源管理复杂问题(多个线程同时操作dom,以哪个为准),因此被设计成为了单线程语言.

说起异步就不得不提回调, 为了解决多重回调嵌套导致代码难以维护问题.javascript一直都在完善这个解决方案.

在10多年中javascript 异步流程控制经过了

callback -> event -> promise -> yield & co -> async await

Callback

ES6之前异步编程最常用的方法,如果回调函数嵌套层数较深,代码将变得难以维护.并且在回调函数之外无法捕获回调函数中的异常.

var fs = require('fs')try {  fs.readFile('file', 'utf8', function(err, data){    // if (err) {
// console.log(err) // } else {
console.log(data) // } })} catch(e) { console.log(e)} 复制代码

尝试读取一个不存在的文件时.外层的try/catch 无法捕获这一异常.将输出 undefine. callback异步操作,异步调用的本体和callback属于不同的事件循环.而try/catch 只能捕获当前事件的异常.因此将无法捕获

Event (发布/订阅模式)

采用事件驱动模式.任务的执行不取决于代码的顺序,由某个事件来决定

var EventEmitter = require('events') var fs = require('fs')var eve = new EventEmitter()// 监听read事件eve.on('read', function(value){  console.log(value)})// 执行一个异步读取fs.readFile('./template.txt', 'utf8', function (err, data) {  if (err) {    console.log(err)  } else {    // 拿到数据后 发送一个read事件.并传递数据     eve.emit('read', data)  }})复制代码

Promise

在ES6中提供了promise对象.给外界提供了统一的API.可用同步操作的流程来表达异步操作.避免了callback 中的嵌套层数过深,不便维护的弊端.

var fs = require('fs')function read (path) {  return new Promise(function(resolve, reject){    fs.readFile(path, 'utf8', function(err, data){      if (err) {        reject(err)      } else {        console.log(data)        resolve()      }    })  })}read('./1.txt').then(function(){  return read('./2.txt')}).then(function(){  return read('./3.txt')}).then(function(){  console.log('执行结束')})复制代码

yield && co

通过Generator函数封装异步任务.在需要暂停的地方使用yield

var fs = require('fs')function *getData () { var a = yield readFile('./1.txt') console.log(a) var b =  yield readFile('./2.txt') console.log(b) var c =  yield readFile('./3.txt') console.log(c)}function readFile(path) {  return new Promise(function(resolve, reject){    fs.readFile(path, 'utf8', function (err, data) {      if (err) {        reject(err)      } else {        resolve(data)      }    })  })}function co(gen) {  var fn = gen()  var lastVal  return new Promise(function(resolve, reject){    !function next(lastVal) {      var {value, done}  = fn.next(lastVal)      if (done) {        resolve()      } else {        value.then(next, reject)      }    }()  })}co(getData)复制代码

async/await

Async/Await应该是目前最简单的异步方案了

  • async 表示这是一个async函数,await只能用在这个函数里面
  • await 表示在这里等待promise返回结果了,再继续执行。
  • await 后面跟着的应该是一个promise对象(其他返回值也可以,只是会立即执行)
  • 捕获错误
var fs = require('fs')async function getData () {  try {    var a = await readFile('file')  } catch(e) {    console.log(e)  }    var b =  await readFile('./2.txt')  console.log(b)  var c =  await readFile('./3.txt')  console.log(c)}function readFile(path) {  return new Promise(function(resolve, reject){    fs.readFile(path, 'utf8', function (err, data) {      if (err) {        reject(err)      } else {        resolve(data)      }    })  })}getData()复制代码

参考文章

转载地址:http://ojqwm.baihongyu.com/

你可能感兴趣的文章
Hello –Test Windows Live Write
查看>>
Ubuntu 更换阿里云源
查看>>
iptables 几条命令
查看>>
FOSCommentBundle功能包:使用ExerciseHTMLPurifierBundle功能包
查看>>
我的友情链接
查看>>
PHP访问一次数据库交互的大致步骤
查看>>
Hadoop读书笔记2 - Hadoop I/O
查看>>
2012您IE了吗?筹备JNCIE之感!
查看>>
安装 puppet_dashboard
查看>>
git 部分递交同一文件中的更改
查看>>
agilent3070 中 analog测试程序的写法
查看>>
我的友情链接
查看>>
某视频公司面试题目
查看>>
破解Linux下的shadow文件获得账户密码
查看>>
在Windows和Linux上安装paramiko模块
查看>>
linux基础命令
查看>>
一个Spring Scheduler (Quartz) 动态添加,删除,修改任务的例子
查看>>
[探讨]如何成为有代码洁癖的程序员?
查看>>
LNMP的虚拟主机安全配置
查看>>
Cannot open /usr/local/varnish/var/varnish/test.localdomain/_.vsm: No such file or directory
查看>>