最近在学习redux-saga,由于redux-saga需要使用Generator函数,所以下来就回顾了一下Generator

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同

写法上Generator函数与普通函数没什么区别,只是在function关键字后面多了一个*号,函数内部多了一个yield关键字

function* demo() {
console.log(1)
yield 111
console.log(2)
yield 222
console.log(3)
return 333
}

上面的函数即为一个Generator函数,Generator调用后并不会直接执行,而是返回一个指向内部状态的指针对象需要调用该指针对象的next方法才会向下执行,当遇到yield关键字的时候,函数会挂起,交给外部,直到遇到下一次调用next方法

let g = demo()

此时若我们第一次调用

let val1 = g.next()

// 打印 1,val1 = {value: 111, done: false}

let val2 = g.next()
// 打印 2,val2 = {value: 222, done: false} let val3 = g.next()
// 打印 3,val3 = {value: 333, done: true}

根据结果我们可以很清楚的看到当返回值的donetrue的时候就代表Generator执行完毕,此外Generator函数还可以被循环


for (let val of demo()) {
console.log(val)
}
// val依次会打印出 111、222,注意当done为true的时候不会打印value的值

当然Generator在工作中最常用到的就是处理异步函数,下面举个例子:


function demo(a, b) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(a + b)
}, 1000)
})
} function* gen(val) {
let a = yield demo(1, 2)
console.log(a)
let b = yield '123'
return b
}

这里需要注意的是,变量a的值是需要next方法传入的

let g = gen()
let {value} = g.next()

此时函数中的变量a的值就是再次调用next传入的值, 比如g.next(value),则此时a的值就是一个Promise的实例,显然这不是我们想要的,我们期望拿到的是Promise.resolve的值

那么根据上面的结果我们可以编写一个Generator执行器

function execGen(gen) {
let g = gen() function deep(val) {
let {value, done} = g.next(val)
if (done) {
return
}
if (value instanceof Promise) {
value.then(data => {
deep(data)
})
} else {
deep(value)
}
}
deep()
} execGen(gen) // gen函数的console会正确的打印出值3

其实如果不是redux-saga的话我感觉我工作中基本不会用到Generator函数,个人感觉更优雅的是async/await 来处理异步情况

async function handler() {
try{
let val = await demo()
}catch (e) { }
}

最后还是期望有大佬能够帮忙指出相比于async/await,Generator有什么优势_

学习笔记:javascript中的Generator函数的更多相关文章

  1. JavaScript中的Generator函数

    1. 简介 Generator函数时ES6提供的一种异步编程解决方案.Generator语法行为和普通函数完全不同,我们可以把Generator理解为一个包含了多个内部状态的状态机. 执行Genera ...

  2. js学习笔记----JavaScript中DOM扩展的那些事

    什么都不说,先上总结的图~   Selectors API(选择符API) querySelector()方法 接收一个css选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回null ...

  3. 前端学习 第二弹: JavaScript中的一些函数与对象(1)

    前端学习 第二弹: JavaScript中的一些函数与对象(1) 1.apply与call函数 每个函数都包含两个非继承而来的方法:apply()和call(). 他们的用途相同,都是在特定的作用域中 ...

  4. ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

  5. JavaScript 中的回调函数

    原文:http://javascriptissexy.com/ 翻译:http://blog.csdn.net/luoweifu/article/details/41466537 [建议阅读原文,以下 ...

  6. HTML 学习笔记 JavaScript(面向对象)

    现在让我们继续跟着大神的脚步前进 学习一下JavaScript中的面向对象的思想,其实作为一个iOS开发者,对面向对象还是比较熟悉的,但是昨晚看了一下Js中的面向对象,妈蛋 一脸萌比啊.还好有大神.让 ...

  7. JavaScript学习13 JavaScript中的继承

    JavaScript学习13 JavaScript中的继承 继承第一种方式:对象冒充 <script type="text/javascript"> //继承第一种方式 ...

  8. 理解和使用 JavaScript 中的回调函数

    理解和使用 JavaScript 中的回调函数 标签: 回调函数指针js 2014-11-25 01:20 11506人阅读 评论(4) 收藏 举报  分类: JavaScript(4)    目录( ...

  9. Javascript学习2 - Javascript中的表达式和运算符

    原文:Javascript学习2 - Javascript中的表达式和运算符 Javascript中的运算符与C/C++中的运算符相似,但有几处不同的地方,相对于C/C++,也增加了几个不同的运算符, ...

随机推荐

  1. halcon 模板匹配 -- create_shape_model

    create_shape_model(Template : : //reduce_domain后的模板图像 NumLevels,//金字塔的层数,可设为“auto”或0—10的整数 AngleStar ...

  2. nginx负载均衡及反向代理

    1.启动,重启,关闭 启动:/usr/local/nginx/sbin/nginx (/usr/local/nginx/sbin/nginx -t 查看配置信息是否正确) 重启:/usr/local/ ...

  3. Deutsch lernen (15)

    1.    unterscheiden - unterschied - unterschieden  区别,区分:(能够)分清 Die beiden Begriffe sind nur schwer ...

  4. I2C controller core之Bit controller(01)

    FPGA proven, AISC proven, I2C controller core from OpenCores http://opencores.org/project,i2c Bit-co ...

  5. Generics of a Higher Kind

    http://adriaanm.github.io/files/higher.pdf https://www.atlassian.com/blog/archives/scala-types-of-a- ...

  6. PKCS #1 RSA Encryption Version 1.5 填充方式

    在进行RSA运算时需要将源数据D转化为Encryption block(EB).其中pkcs1padding V1.5的填充模式安装以下方式进行 (1) EB = 00+ BT+PS +00 + D ...

  7. Java RMI之HelloWorld经典入门案例

    Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...

  8. 拓扑排序(Topological Order)

    Date:2019-06-17 14:43:59 算法描述 1.定义队列Q,并把所有入度为0的结点加入队列 2.取队首结点,输出.然后删除所有从它除法的边,并令这些边到达的顶点的入度-1,若某个顶点的 ...

  9. Clocksource tsc unstable

    内核在启动过程中会根据既定的优先级选择时钟源.优先级的排序根据时钟的精度与访问速度. 其中CPU中的TSC寄存器是精度最高(与CPU最高主频等同),访问速度最快(只需一条指令,一个时钟周期)的时钟源, ...

  10. 洛谷P1025 数的划分【dp】

    将整数nn分成kk份,且每份不能为空,任意两个方案不相同(不考虑顺序). 例如:n=7n=7,k=3k=3,下面三种分法被认为是相同的. 1,1,51,1,5; 1,5,11,5,1; 5,1,15, ...