读书笔记-你不知道的JS中-函数生成器
这个坑比较深 可能写完我也看不懂(逃
ES6提供了一个新的函数特性,名字叫Generator,一开始看到,第一反应是函数指针?然而并不是,只是一个新的语法。
入门
简单来说,用法如下:
function* fn() {
console.log(1);
//暂停!
yield;
//调用next方法继续执行
console.log(2);
}
var iter = fn();
iter.next(); //
iter.next(); //
1、函数生成器特点是函数名前面有一个‘*’
2、通过调用函数生成一个控制器
3、调用next()方法开始执行函数
4、遇到yield函数将暂停
5、再次调用next()继续执行函数
消息传递
除了暂停和继续执行外,生成器同时支持传值。
用法如下:
function* fn() {
var a = yield 'hello';
yield;
console.log(a);
}
var iter = fn();
var res = iter.next();
console.log(res.value); //hello
iter.next(2);
iter.next(); //
可以看到,yield后面有一个字符串,在第一次调用next时,暂停在这里且返回给了iter.next()。
而暂停的地方是一个赋值语句,需要一个变量给a,于是next()方法中传了一个参数2替换了yield,最后打印a得到了2。
异步应用
通过yield来实现异步控制流程:
function fn(a, b) {
//假设这是一个ajax请求
ajax('url' + a + b, function(data) {
//数据请求到会执行it.next
it.next(data);
});
}
//这里是函数生成器
function* g() {
//当异步操作完毕yield会得到值
//这里会自动继续执行
var text = yield fn(a, b);
console.log(text);
}
var it = g();
it.next();
这里做了简化处理,忽略了一些错误处理。
确实很巧妙,通过回调函数来继续执行函数生成器,然后得到数据。
然而,直接在回调里拿数据不行么。书上讲,这样异步操作符合大脑思考模式,函数的执行看起来‘同步’了。
yield+promise
重点来了。
先回忆之前promise对异步的实现:
function request(url) {
return new Promise(function(resolve, reject) {
//ajax异步请求完成会调用resolve决议
ajax(url, resolve);
});
}
request('url').then(function(res) {
console.log(res);
})
流程大概是调用函数传入url,由于会立即决议,触发ajax请求函数。异步请求完调用调用回调函数,也就是resolve,然后根据返回的resolve调用then方法获取数据。
现在将yield与promise综合在一起:
function foo(x) {
return request('url' + x);
}
//等待promise决议值返回
function* fn() {
var text = yield foo(1);
}
var it = fn();
//返回一个promise
var p = it.next().value;
//对promise处理
p.then(function(text) {
//这里继续执行生成器
it.next(text);
})
封装
可以将上面的yield+promise进行封装,得到下面的函数:
function run(gen) {
//获取除了生成器本身以外的参数
var args = [].slice.call(arguments, 1),
it;
//it = main()
it = gen.apply(this, args);
return Promise.resolve().then(function handleNext(value) {
//第一次启动无value
var next = it.next(value);
return (function handleResult(next) {
//执行完毕返回
if (next.done) {
return next.value;
} else {
//如果还有就决议next.value传给handleNext
return Promise.resolve(next.value).then(handleNext, function(err) {});
}
})(next);
});
}
//这是一个函数生成器
function* main() {
//...
};
//该调用会自动异步运行直到结束
run(main);
如果有两个异步操作,获取到返回的两个数据后,再进行第三个异步操作,可以这么做:
function foo() {
var p1 = request('url1'),
p2 = request('url2');
//每一个request异步请求完成后会自动解除yield
var r1 = yield p1,
r2 = yield p2;
var r3 = yield request('url3' + r1 + r2);
console.log(r3);
}
坦白的讲,我不知道该写什么了,看懂后面的再来填坑。
读书笔记-你不知道的JS中-函数生成器的更多相关文章
- 读书笔记-你不知道的JS中-promise
之前的笔记没保存没掉了,好气,重新写! 填坑-- 现在与将来 在单个JS文件中,程序由许多块组成,这些块有的现在执行,有的将来执行,最常见的块单位是函数. 程序中'将来'执行的部分并不一定在'现在'运 ...
- 读书笔记-你不知道的JS上-函数作用域与块作用域
函数作用域 Javascript具有基于函数的作用域,每声明一个函数,都会产生一个对应的作用域. //全局作用域包含f1 function f1(a) { var b = 1; //f1作用域包含a, ...
- 读书笔记-你不知道的JS中-promise(3)
坑坑坑 关于术语:决议.完成以及拒绝. 首先观察Promise(..)构造器: var p = new Promise(function(x, y) { //x() 用于完成 //y() 用于拒绝 } ...
- 读书笔记-你不知道的JS中-promise(2)
继续填坑 模式 考虑下面的代码: function fn(x) { //do something return new Promise(function(resolve, reject) { //调用 ...
- 读书笔记-你不知道的JS上-对象
好想要对象··· 函数的调用位置不同会造成this绑定对象不同.但是对象到底是什么,为什么要绑定他们呢?(可以可以,我也不太懂) 语法 对象声明有两个形式: 1.字面量 => var obj = ...
- 读书笔记-你不知道的JS上-this
关于this 与静态词法作用域不用,this的指向动态绑定,在函数执行期间才能确定.感觉有点像C++的多态? var a = 1; var obj = { a: 2, fn: function() { ...
- 读书笔记-你不知道的JS上-词法作用域
JS引擎 编译与执行 Javascript引擎会在词法分析和代码生成阶段对运行性能进行优化,包含对冗余元素进行优化(例如对语句在不影响结果的情况下进行重新组合). 对于Javascript来说,大部分 ...
- 读书笔记-你不知道的JS上-混入与原型
继承 mixin混合继承 function mixin(obj1, obj2) { for (var key in obj2) { //重复不复制 if (!(key in obj1)) { obj1 ...
- 读书笔记-你不知道的JS上-闭包与模块
闭包定义 当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行. 看一段最简单的闭包代码: function foo() { var a = 2; //闭包 fun ...
随机推荐
- spring boot基础 入门
spring boot基础 spring boot 的简单搭建 spring boot 的基本用法 spring boot 基本用法 自动配置 技术集成 性能监控 源码解析 工程的构建 创建一个mav ...
- 轻松把你的项目升级到PWA
什么是PWA PWA(Progressive Web Apps,渐进式网页应用)是Google在2015年推出的项目,致力于通过web app获得类似native app体验的网站. 优点 1.无需客 ...
- mapreduce自定义排序(map端1.4步)
3 3 3 2 3 1 2 2 2 1 1 1 -----------------期望输出 1 1 2 1 2 2 3 1 3 2 3 3 将以上数据进行排序,排序规则是:按照第一列升序排序,如果第一 ...
- 一款简单而不失强大的前端框架——【Vue.js的详细入门教程①】
↓— Vue.js框架魅力 —↓ 前言 Vue.js 是一个构建数据驱动的 web 界面的渐进式框架.Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件.V ...
- SoapUI简介和入门实例解析
SoapUI简介 SoapUI是一个开源测试工具,通过soap/http来检查.调用.实现Web Service的功能/负载/符合性测试.该工具既可作为一个单独的测试软件使用,也可利用插件集成到Ecl ...
- 用Atom打造简单的java编译器以及对于可能出现的问题解答
如何用Atom打造简单的javaIDE 自己一直比较喜欢Atom编辑器,前段时间给Atom配置好了C/C++的运行环境,自己心里还是感觉挺好的,最近在学习java ,偶然的机会让我看到了一篇文章,就是 ...
- IDEA- idea代码调试debug
IDEA有很多的快捷键,下面整理Debug的快捷键,方便自己使用!(阅读本篇可能花费您2分钟,需要多的实践练习) F9 resume programe 恢复程序 Alt+F10 show execut ...
- Linux入门(7) 脚本
1.宣告使用的shell为何 2.注明创建者 编写作用等 3.注释每一个功能函数 执行脚本 1.修改可执行权限 chmod 755 file.sh 2.sh file.sh 可以直接运行脚本 #!/b ...
- jQuery ajax的提交
1.利用jQuery中的aja提交数据,首先引入jQuery中的文件 2.jquery.form.js下载地址:http://vdisk.weibo.com/s/thY_x31gX0M-p?categ ...
- 【机器学习实战】第6章 支持向量机(Support Vector Machine / SVM)
第6章 支持向量机 <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/lates ...