Promise不仅能够捕获错误,而且也很好地解决了回调地狱的问题,可以把之前的回调地狱例子改写为如下代码:
- ajax(url)
- .then(res => {
- console.log(res)
- return ajax(url1)
- }).then(res => {
- console.log(res)
- return ajax(url2)
- }).then(res => console.log(res))
它也是存在一些缺点的,比如无法取消 Promise,错误需要通过回调函数捕获。
六、生成器Generators/ yield
Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同,Generator 最大的特点就是可以控制函数的执行。
- 语法上,首先可以把它理解成,,Generator 函数是一个状态机,封装了多个内部状态。
- Generator 函数除了状态机,还是一个遍历器对象生成函数。
- 可暂停函数, yield可暂停,next方法可启动,每次返回的是yield后的表达式结果。
- yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
我们先来看个例子:
- function *foo(x) {
- let y = 2 * (yield (x + 1))
- let z = yield (y / 3)
- return (x + y + z)
- }
- let it = foo(5)
- console.log(it.next()) // => {value: 6, done: false}
- console.log(it.next(12)) // => {value: 8, done: false}
- console.log(it.next(13)) // => {value: 42, done: true}
可能结果跟你想象不一致,接下来我们逐行代码分析:
- 首先 Generator 函数调用和普通函数不同,它会返回一个迭代器
- 当执行第一次 next 时,传参会被忽略,并且函数暂停在 yield (x + 1) 处,所以返回 5 + 1 = 6
- 当执行第二次 next 时,传入的参数12就会被当作上一个yield表达式的返回值,如果你不传参,yield 永远返回 undefined。此时 let y = 2 12,所以第二个 yield 等于 2 12 / 3 = 8
- 当执行第三次 next 时,传入的参数13就会被当作上一个yield表达式的返回值,所以 z = 13, x = 5, y = 24,相加等于 42
我们再来看个例子:有三个本地文件,分别1.txt,2.txt和3.txt,内容都只有一句话,下一个请求依赖上一个请求的结果,想通过Generator函数依次调用三个文件
- //1.txt文件
- 2.txt
- //2.txt文件
- 3.txt
- //3.txt文件
- 结束
- let fs = require('fs')
- function read(file) {
- return new Promise(function(resolve, reject) {
- fs.readFile(file, 'utf8', function(err, data) {
- if (err) reject(err)
- resolve(data)
- })
- })
- }
- function* r() {
- let r1 = yield read('./1.txt')
- let r2 = yield read(r1)
- let r3 = yield read(r2)
- console.log(r1)
- console.log(r2)
- console.log(r3)
- }
- let it = r()
- let { value, done } = it.next()
- value.then(function(data) { // value是个promise
- console.log(data) //data=>2.txt
- let { value, done } = it.next(data)
- value.then(function(data) {
- console.log(data) //data=>3.txt
- let { value, done } = it.next(data)
- value.then(function(data) {
- console.log(data) //data=>结束
- })
- })
- })
- // 2.txt=>3.txt=>结束
(编辑:我爱故事小小网_铜陵站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|