Generator与异步编程概述

在《深入浅出Node.js》的第4章里,笔者深入地介绍了当前盛行在Node和前端JavaScript中的几种异步编程的解决方案,唯独对Generator的解决方案没有介绍。但随着Node版本的升级和ECMAScript harmony的特性不断得到支持,在0.11版本中,我们可以通过启用--harmory参数让V8支持Generator。最近Connect/Express背后的开发团队也将精力转移到新的库和框架上,这个核心库和框架就是co和koa,它们最主要的特点主要就是基于ECMAScript harmony中的Generator特性,这使得它在异步编程方面有较优雅的实现。

本文将深度介绍下Generator是如何实现将异步编程从原始的嵌套式代码转换成扁平的顺序式代码。

异步编程问题回顾

简单地回顾下,异步编程的问题主要有两个:一个是必须通过回调函数进行返回值的处理,另一个是复杂情况下会造成嵌套过深。下面简单的给出两种典型的异步场景。

异步串行读取文件:

fs.readFile('file1.txt', 'utf8', function (err, txt) {
  if (err) {
    throw err;
  }
  fs.readFile(txt, 'utf8', function (err, content) {
    if (err) {
      throw err;
    }
    console.log(content);
  });
});

异步并行读取文件:

fs.readFile('file1.txt', 'utf8', function (err, txt) {
  if (err) {
    throw err;
  }
  console.log(txt);
});
fs.readFile('file2.txt', 'utf8', function (err, content) {
  if (err) {
    throw err;
  }
  console.log(content);
});

上述两种场景下,可以看到串行时由于代码嵌套,调用越多,会造成代码越糟糕。对于异步并行读取文件的代码,难点是无法获知并行异步调用完全完成的时间点,要解决这个问题需要借助各种异步流程库。

目前解决异步流程控制问题的主流方案有以下三种:

自定义事件式方案

Promise/Deferred

高阶函数篡改回调函数

由于在《异步编程》章节中已经充分介绍了上述三种方式的实现形式,这里不再详细展开三种方式的细节。但是为了行文承前启后,这里简单回顾下第三种方案的实现。

高阶函数在异步编程中的使用

高阶函数在异步编程中的使用,最广泛、最知名的莫过于async和step这两个库,它将用户正常传递进来的回调函数替换成自己包装了特殊逻辑的函数,然后再传递给异步调用。当异步调用结束后,先执行的是特殊逻辑,然后才是用户传入的回调函数。以一个简单的场景为例,假设需要等待所有异步回调执行完成后,才能执行某个逻辑,这时通过高阶函数篡改回调函数的方式就大为受用,也相当简单。以下为简单实现:

var pending = (function () {
  var count = 0;
  return function (callback) {
    count++;
    return function () {
      count--;
      if (count === 0) {
        callback();
      }
    };
  };
}());

var done = pending(function () {
  console.log('all is over');
});

fs.readFile('file1.txt', 'utf8', done());
fs.readFile('file2.txt', 'utf8', done());

上述代码中,done执行了两次,每次执行的过程中,将计数器count加一,然后返回一个函数。当fs.readFile这个异步调用结束后,done执行后的回调函数会得到执行,计数器减一。当计数器回到0的时候,意味着多个异步调用的回调函数都已经执行,此时执行传入的回调函数。因为非阻塞的原因,done()生成的函数不会立即执行,使得计数器可以正常地增加值,结束后才慢慢减少值。

抛开异步调用不谈,高阶函数的试用上,要让用户传入的函数能得到执行。需要如下这种方式的调用:

var done = pending(function () {
  console.log('all is over');
});

done()();

这里生成的函数被立即调用了,count这个计数器加一后,立即减一,然后触发等于零的条件,于是回调函数被执行了。

在通过Generator解决异步编程问题的方案中,高阶函数与Generator之间会产生相当微妙的化学反应。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索异步编程
, 编程
, 并行函数库
, 函数
, 异步
, function
, generator
, err
, readfile
, utf-8struts2.0异步
, 异步执行
, Koa
, 异步文件下载
异步回调
es6 generator 异步、generator 异步、c 异步编程、异步编程、java异步编程,以便于您获取更多的相关知识。

时间: 2024-09-11 11:25:36

Generator与异步编程概述的相关文章

JavaScript异步编程解决方案

最近看了一些javascript异步编程方面文章, 也反复读了几遍薄薄的 << Async JavaScript >>.总结一下, 供自己后续学习使用, 并分享给大家. 首先, 有几个问题: 什么是异步编程/异步函数? 异步函数和回调函数有什么关系? 为什么异步编程经常与javascript同时出现? javascript中的异步函数的机制是怎样的? 那么现在异步编程有什么解决文案? 未来的javascript异步编程是什么样子? 什么是异步函数? 对一个jser而言,学习和使用j

C#网络编程概述

编程|网络 C#网络编程概述 微软下一代互联网开发工具VS.Net已于三月份在全国范围推出,其中的一门新兴语言C#正被越来越多的开发者所接受并运用. C#作为一门集众家之长的语言,在各个方面尤其是网络编程方面有着很大的优势.本文就向大家介绍一下用C#进行网络编程的一些基本知识和方法. 微软的.Net框架为我们进行网络编程提供了以下两个名字空间:System.Net以及System.Net.Sockets.通过合理运用其中的类和方法,我们可以很容易地编写出各种网络应用程序.这种网络应用程序既可以是

C#基础学习 —— 异步编程篇 (二)

基于事件的异步模式是比 IAsyncResult 模式更高级的一种异步编程模式,也被用在更多的场合.对于相对简单的应用程序可以直接用 .Net 2.0 新增的 BackgroundWorker 组件来很方便的实现,对于更复杂的异步应用程序则需要自己实现一个符合基于事件的异步模式的类.这两者对我都是新东西,先从简单的入手,下一篇里我再去尝试复杂类模型的实现 模式概述 支持基于事件的异步模式的类会有若干个 MethodNameAsync 方法表示开始异步操作,并有对应的 MethodNameComp

C#并发编程经典实例--并发编程概述

来自 "C#并发编程经典实例" 优秀软件的一个关键特征就是具有并发性.过去的几十年,我们可以进行并发编程,但是难度很大.以前,并发性软件的编写.调试和维护都很难,这导致很多开发人员为图省事放弃了并发编程.新版.NET 中的程序库和语言特征,已经让并发编程变得简单多了.随着Visual Studio 2012 的发布,微软明显降低了并发编程的门槛.以前只有专家才能做并发编程,而今天,每一个开发人员都能够(而且应该)接受并发编程. 1.1 并发编程简介 首先,我来解释几个贯穿本书始终的术语

探索Javascript异步编程

异步编程带来的问题在客户端Javascript中并不明显,但随着服务器端Javascript越来越广的被使用,大量的异步IO操作使得该问题变得明显.许多不同的方法都可以解决这个问题,本文讨论了一些方法,但并不深入.大家需要根据自己的情况选择一个适于自己的方法. 笔者在之前的一片博客中简单的讨论了Python和Javascript的异同,其实作为一种编程语言Javascript的异步编程是一个非常值得讨论的有趣话题. JavaScript 异步编程简介 回调函数和异步执行 所谓的异步指的是函数的调

一篇需要膜拜的文篇--Javascript异步编程模型进化(转)

要我能用得这么熟, 那前端出师了哈. http://foio.github.io/javascript-asyn-pattern/ 改天一个一个亲测一下. Javascript语言是单线程的,没有复杂的同步互斥:但是,这并没有限制它的使用范围:相反,借助于Node,Javascript已经在某些场景下具备通吃前后端的能力了.近几年,多线程同步IO的模式已经在和单线程异步IO的模式的对决中败下阵来,Node也因此得名.接下来我们深入介绍一下Javascript的杀手锏,异步编程的发展历程. 让我们

JS魔法堂:深究JS异步编程模型

前言  上周5在公司作了关于JS异步编程模型的技术分享,可能是内容太干的缘故吧,最后从大家的表情看出"这条粉肠到底在说啥?"的结果:(下面是PPT的讲义,具体的PPT和示例代码在https://github.com/fsjohnhuang/ppt/tree/master/apm_of_js上,有兴趣就上去看看吧! 重申主题  <异步编程模型>这个名称确实不太直观,其实今天我想和大家分享的就是上面的代码是如何演进成下面的代码而已. a(function(){ b(functi

详谈nodejs异步编程_node.js

目前需求中涉及到大量的异步操作,实际的页面越来越倾向于单页面应用.以后可以会使用backbone.angular.knockout等框架,但是关于异步编程的问题是首先需要面对的问题.随着node的兴起,异步编程成为一个非常热的话题.经过一段时间的学习和实践,对异步编程的一些细节进行总结. 1.异步编程的分类      解决异步问题方法大致包括:直接回调.pub/sub模式(事件模式).异步库控制库(例如async.when).promise.Generator等. 1.1 回调函数      

跟我学习javascript解决异步编程异常方案_javascript技巧

一.JavaScript异步编程的两个核心难点 异步I/O.事件驱动使得单线程的JavaScript得以在不阻塞UI的情况下执行网络.文件访问功能,且使之在后端实现了较高的性能.然而异步风格也引来了一些麻烦,其中比较核心的问题是: 1.函数嵌套过深 JavaScript的异步调用基于回调函数,当多个异步事务多级依赖时,回调函数会形成多级的嵌套,代码变成 金字塔型结构.这不仅使得代码变难看难懂,更使得调试.重构的过程充满风险. 2.异常处理 回调嵌套不仅仅是使代码变得杂乱,也使得错误处理更复杂.这