文章同步自个人博客:http://www.52cik.com/2016/07/11/generator-co.html

此前只是简单使用而没有真正的去研究 Generator,这次要好好折腾下这货。

异步编程

对于 jser 来说,异步非常熟悉了吧,但是真正理解异步的却不多,因为大部分人只知道回调。

随着js的快速发展,异步方案也层出不穷,从最开始的回调到Promise,再到Generator,然后到async/await。

甚至有人说 async/await 是异步的终极解决方案,我不敢直接赞同,只能说是目前最好的异步体验。

本篇先从 Generator 讲起,后序再详细说 async/await。

从回调开始

从最最经典的 ajax 请求开始今天的话题吧。

假如,我们要依次请求 url1, url2, url3 这3个地址。

$.get('url1', function(r1) {
$.get('url2', function(r2) {
$.get('url3', function(r3) {
console.log(r1, r2, r3);
});
});
});

一不小心就写成这样了。

如果你是 jQuery 粉的话,你可能会说也可以这样实现啊。

$.get('url1').then(function(r1) {
console.log(r1);
return $.get('url2');
}).then(function(r2) {
console.log(r2);
return $.get('url3');
}).then(function(r3) {
console.log(r3);
});

用 jQuery 的 Deferred 对象,类似 Promise 来规避回调地狱,看着确实平了,但体验并不是特别友好。

用 Generator 来和谐回调

Generator 的基础这里就不展开说了,直接说应用。

function* gen() {
var r1 = yield $.get('url1');
var r2 = yield $.get('url2');
var r3 = yield $.get('url3'); console.log(r1, r2, r3);
}

这是比较友好的异步方式,但是还有个至关重要的因素,怎么运行这个 Generator 是个问题。

直接手动 g.next() 运行那肯定不行,鬼知道有多少个 yield。

我们要实现一个启动器来运行它,并把 Promise 结果传给下一次next,这样就实现了 yield 接收值的功能。

先来实现一个最简陋的起动器。

function run(gen) {
var g = gen(); function next(d) {
var r = g.next(d);
r.done || r.value.then(function(d){ next(d) }); // 这个是关键,把值传回传
} next();
}

然后我们只要一行代码。

run(gen);

Generator 就启动起来了,并且一直执行到 done 为 true 为止。

真实例子

打开 http://www.52tian.net/ 动漫网。非广告,确实没找到合适的测试站,凑合下吧。

然后把下面代码贴到控制台,看下结果。如果执行不了,请升级浏览器,本例在 chrome 51 下通过。

function* gen() {
var r1 = yield $.get('/json/anime/4126.htm');
var r2 = yield $.get('/json/anime/11129.htm');
var r3 = yield $.get('/json/anime/427.htm'); console.log([r1, r2, r3].join('\n'));
} function run(gen) {
var g = gen(); function next(d) {
var r = g.next(d);
r.done || r.value.then(function(d){ next(d) }); // 这个是关键,把值传回传
} next();
} run(gen);

小结

可能你已经发现了,其实这就是 co 的原理,但 co 比这个例子严谨多了,而且api设计的也非常友好。

本篇到此也就结束了,利用 Generator 的 yield 功能实现参数回传,让代码看起来非常‘同步’,让异步体验变的更加友好。

让 Generator 自启动的更多相关文章

  1. async 更优雅异步体验

    上一篇<让 Generator 自启动>介绍了通过起动器让 Generator 跑起来,而本篇采用 async 实现更优雅的异步编程. 从例子开始 借用上一篇例子中的例子说起. funct ...

  2. linux程序自启动和新建linux服务的方法

    1 linux创建自启动程序    自启动的两种方法,都经过自己测试.1.1 自启动程序方法1:    在etc/rc.local在里面加入/home/robin/code/autoruntest & ...

  3. EasyMesh - A Two-Dimensional Quality Mesh Generator

    EasyMesh - A Two-Dimensional Quality Mesh Generator eryar@163.com Abstract. EasyMesh is developed by ...

  4. 轻量级“集合”迭代器-Generator

    Generator是PHP 5.5加入的新语言特性.但是,它似乎并没有被很多PHP开发者广泛采用.因此,在我们了解PHP 7对Generator的改进之前,我们先通过一个简单却显而易见的例子来了解下G ...

  5. .NET平台开源项目速览(18)C#平台JSON实体类生成器JSON C# Class Generator

    去年,我在一篇文章用原始方法解析复杂字符串,json一定要用JsonMapper么?中介绍了简单的JSON解析的问题,那种方法在当时的环境是非常方便的,因为不需要生成实体类,结构很容易解析.但随着业务 ...

  6. 深入解析js异步编程利器Generator

    我们在编写Nodejs程序时,经常会用到回调函数,在一个操作执行完成之后对返回的数据进行处理,我简单的理解它为异步编程. 如果操作很多,那么回调的嵌套就会必不可少,那么如果操作非常多,那么回调的嵌套就 ...

  7. mybatis Generator生成代码及使用方式

    本文原创,转载请注明:http://www.cnblogs.com/fengzheng/p/5889312.html 为什么要有mybatis mybatis 是一个 Java 的 ORM 框架,OR ...

  8. ABP配套代码生成器(ABP Code Generator)帮助文档,实现快速开发

    ABP代码生成器介绍 针对abp这个框架做了一个代码生成器,功能强大.分为两大功能点,一个是数据层,一个是视图层. 数据服务层:通过它,可以实现表设计.领域层初始化.多语言.automapper自动注 ...

  9. ES6笔记(5)-- Generator生成器函数

    系列文章 -- ES6笔记系列 接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术. 在异步编程中,还 ...

随机推荐

  1. ORACLE 如何查看索引重建进度情况

    在ORACLE数据库中,如果一个比较大的索引在重建过程中耗费时间比较长,那么怎么查看索引重建耗费的时间,以及完成了多少(比例)了呢,我们可以通过V$SESSION_LONGOPS视图来查看索引重建的时 ...

  2. [Config]Zabbix的Mongodb插件安装,centos

    1.yum install php-devel php-pear httpd-devel 2.安装mongo php驱动,pecl install mongo 3.pecl install mongo ...

  3. JBOSS目录结构详细说明

    一.下载与安装. 如何下载以及安装配置,请参考:Windows下JBOSS安装配置图文教程 二.现在主要了解一下JBOSS目录结构. 1. 主目录: E:\jboos\jboss-6.1.0.Fina ...

  4. db2数组、函数

    一. 数组 在db2中,创建一个数组会在functions下生成两个对象:sys类型和用户类型的Array /*创建数组*/ ) array[]; /*删除数组*/ drop type arrName ...

  5. 001.libev安装及eclipse下添加libev库链接

    libev库安装: 1.下载页面:http://dist.schmorp.de/libev/ 当前版本下载: [root@mid_server ~]# cd /usr/local/src  [root ...

  6. Linux设置环境变量小结:设置永久变量&临时变量 全局变量&局部变量

    1.总结背景 在linux系统下,如果你下载并安装了应用程序,很有可能在键入它的名称时出现“command not found”的提示内容.如果每次都到安装目标文件夹内,找到可执行文件来进行操作就太繁 ...

  7. 理解 Linux 网络栈(1):Linux 网络协议栈简单总结

    本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...

  8. jquery对标签属性操作

    jquery中添加属性和删除属性: $("#2args").attr("disabled",'disabled'); $("#2args") ...

  9. BFC 小结

    最近对一些基础知识进行了整理,下面是针对 BFC 的一些整理以及本人对 BFC 的一些理解. 1. 首先,什么是 BFC 呢? BFC,Block formatting context,直译为&quo ...

  10. NOIP2010提高组 机器翻译 -SilverN

    /**/ #include<iostream> #include<cstdio> #include<cmath> #include<cstring> # ...