资讯专栏INFORMATION COLUMN

JavaScript异步流程控制的前世今生

刘明 / 3548人阅读

摘要:后面跟着的应该是一个对象其他返回值也可以,只是会立即执行捕获错误参考文章函数的含义与用法

JavaScript异步流程控制的前世今生

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()

参考文章
Generator 函数的含义与用法

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92574.html

相关文章

  • python协程前世今生

    摘要:协程的历史说来话长,要从生成器开始讲起。我们可以使用把数据发送给协程函数。可以看到,在第次接收完数据之后,会产生结束的异常,因为程序流程结束了,这是正常现象。在这个阶段,协程本质上还是由生成器构成的。所以,协程的介绍到这里就结束啦。 在上一篇对python并发编程的理解 中,我简单提到了协程的概念,有一个错误需要指出的是,asyncio不全是对协程的实现,只是用到了协程。 协程的历史说...

    stackfing 评论0 收藏0
  • TWaver可视化编辑器前世今生(三)Doodle

    摘要:随着越来越多的商业项目采用了和,可视化的概念也越来越深入人心。深知一款优秀的编辑器工具,将大幅减少工程师和项目实施人员的工作量,就像编辑器在内部使用时一样。的发布,标志着已经形成了内部使用,客户定制,标准化产品三位一体的编辑器解决方案。 插播一则广告(长期有效) MONO哥需要在武汉招JavaScript工程师若干要求:对前端技术(JavasScript、HTML、CSS),对可视化技...

    DevWiki 评论0 收藏0
  • Web技术前世今生(三)

    摘要:前言我是,如果你还不认识我,不妨先看看技术的前世今生一,以及技术的前世今生二前面我提过,我的大哥有一个叫的死党,这家伙有事没事经常上我们家串门。时间来到了年,在那前后发生了两件事让我印象深刻。传送门技术的前世今生一技术的前世今生二 前言:我是JavaScript,如果你还不认识我,不妨先看看《Web技术的前世今生(一)》,以及《Web技术的前世今生(二)》 前面我提过,我的大哥HTML...

    Wuv1Up 评论0 收藏0
  • Web技术前世今生(二)

    摘要:前言我是,如果你还不认识我,不妨先看看技术的前世今生一平静的生活已经有一段日子了。传送门技术的前世今生一技术的前世今生三 前言:我是JavaScript,如果你还不认识我,不妨先看看《Web技术的前世今生(一)》 平静的生活已经有一段日子了。 这一天,HTML大哥面露不悦地走过来问我: Js,你是打算和我们分家吗? 大哥,您这说的哪里话,我什么地方做的不对么?我一脸茫然地回答道。 哼,...

    Stardustsky 评论0 收藏0
  • Web技术前世今生(二)

    摘要:前言我是,如果你还不认识我,不妨先看看技术的前世今生一平静的生活已经有一段日子了。传送门技术的前世今生一技术的前世今生三 前言:我是JavaScript,如果你还不认识我,不妨先看看《Web技术的前世今生(一)》 平静的生活已经有一段日子了。 这一天,HTML大哥面露不悦地走过来问我: Js,你是打算和我们分家吗? 大哥,您这说的哪里话,我什么地方做的不对么?我一脸茫然地回答道。 哼,...

    hyuan 评论0 收藏0

发表评论

0条评论

刘明

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<