加入收藏 | 设为首页 | 会员中心 | 我要投稿 我爱故事小小网_铜陵站长网 (http://www.0562zz.com/)- 视频终端、云渲染、应用安全、数据安全、安全管理!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

JS异步编程六种方案

发布时间:2019-01-30 17:28:51 所属栏目:优化 来源:浪里行舟
导读:副标题#e# 前言 我们知道Javascript语言的执行环境是单线程。也就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务。 这种模式虽然实现起来比较简单,执行环境相对单纯,但是只要有一个任务耗时很长,后面的任

Promise不仅能够捕获错误,而且也很好地解决了回调地狱的问题,可以把之前的回调地狱例子改写为如下代码:

  1. ajax(url)  
  2.   .then(res => {  
  3.       console.log(res)  
  4.       return ajax(url1)  
  5.   }).then(res => {  
  6.       console.log(res)  
  7.       return ajax(url2)  
  8.   }).then(res => console.log(res)) 

它也是存在一些缺点的,比如无法取消 Promise,错误需要通过回调函数捕获。

六、生成器Generators/ yield

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同,Generator 最大的特点就是可以控制函数的执行。

  •  语法上,首先可以把它理解成,,Generator 函数是一个状态机,封装了多个内部状态。
  •  Generator 函数除了状态机,还是一个遍历器对象生成函数。
  •  可暂停函数, yield可暂停,next方法可启动,每次返回的是yield后的表达式结果。
  •  yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。

我们先来看个例子:

  1. function *foo(x) {  
  2.   let y = 2 * (yield (x + 1))  
  3.   let z = yield (y / 3)  
  4.   return (x + y + z)  
  5. }  
  6. let it = foo(5)  
  7. console.log(it.next())   // => {value: 6, done: false}  
  8. console.log(it.next(12)) // => {value: 8, done: false}  
  9. 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. //1.txt文件  
  2. 2.txt  
  1. //2.txt文件  
  2. 3.txt  
  1. //3.txt文件  
  2. 结束  
  1. let fs = require('fs')  
  2. function read(file) {  
  3.   return new Promise(function(resolve, reject) {  
  4.     fs.readFile(file, 'utf8', function(err, data) {  
  5.       if (err) reject(err)  
  6.       resolve(data)  
  7.     })  
  8.   })  
  9. }  
  10. function* r() {  
  11.   let r1 = yield read('./1.txt')  
  12.   let r2 = yield read(r1)  
  13.   let r3 = yield read(r2)  
  14.   console.log(r1)  
  15.   console.log(r2)  
  16.   console.log(r3)  
  17. }  
  18. let it = r()  
  19. let { value, done } = it.next()  
  20. value.then(function(data) { // value是个promise  
  21.   console.log(data) //data=>2.txt  
  22.   let { value, done } = it.next(data)  
  23.   value.then(function(data) {  
  24.     console.log(data) //data=>3.txt  
  25.     let { value, done } = it.next(data)  
  26.     value.then(function(data) {  
  27.       console.log(data) //data=>结束  
  28.     })  
  29.   })  
  30. })  
  31. // 2.txt=>3.txt=>结束 

(编辑:我爱故事小小网_铜陵站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读