文章同步自我的博客:http://www.52cik.com/2016/07/11/generator-co.htmlhtml
此前只是简单使用而没有真正的去研究 Generator,此次要好好折腾下这货。ajax
对于 jser 来讲,异步很是熟悉了吧,可是真正理解异步的却很少,由于大部分人只知道回调。
随着js的快速发展,异步方案也层出不穷,从最开始的回调到Promise,再到Generator,而后到async/await。
甚至有人说 async/await 是异步的终极解决方案,我不敢直接赞同,只能说是目前最好的异步体验。
本篇先从 Generator 讲起,后序再详细说 async/await。chrome
从最最经典的 ajax 请求开始今天的话题吧。
假如,咱们要依次请求 url1, url2, url3 这3个地址。编程
$.get('url1', function(r1) { $.get('url2', function(r2) { $.get('url3', function(r3) { console.log(r1, r2, r3); }); }); });
一不当心就写成这样了。
若是你是 jQuery 粉的话,你可能会说也能够这样实现啊。json
$.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 来规避回调地狱,看着确实平了,但体验并非特别友好。api
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 接收值的功能。异步
先来实现一个最简陋的起动器。async
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 功能实现参数回传,让代码看起来很是‘同步’,让异步体验变的更加友好。