time 4m9s
image.png

迭代器模式与迭代器

time 8m
迭代器模式,结构化模式:从源 以一次一个的方式抽取;
image.png
迭代器是迭代器模式的具体实现,是迭代器模式的一种实现方式

内部迭代器
系统帮我们定义好的

内部迭代器与外部迭代器的区别在于它的实现方式,调用方式是不一样的,一个是通过系统内部的方法进行迭代的,比如for of、for each、array.from等,像这种方式都是调用的系统内部的迭代器接口

外部迭代器是我们自己通过手动的方式来定义的,就像之前上面的代码,自己写的,不是系统内部的

对象抽取

因为对象不是有序的连续的,所以没有办法抽取
time 17m48s
image.png

map是有序且连续的

time 19m39s
image.png

time 34m

obj与迭代器

time 39m58s
image.png
image.png

  1. let obj = {
  2. a: 1,
  3. b: 2,
  4. c: 3,
  5. [Symbol.iterator]() {
  6. let nextIndex = 0;
  7. let map = new Map();
  8. for (let [key, value] of Object.entries(this)) {
  9. map.set(key, value)
  10. }
  11. let mapEntries = [...map.entries()];
  12. return {
  13. next() {
  14. return nextIndex < mapEntries.length ?
  15. {value: mapEntries[nextIndex++], done: false} :
  16. {value: undefined, done: true}
  17. }
  18. }
  19. }
  20. }
  21. for (let i of obj) {
  22. console.log(i);
  23. }
  24. /*[ 'a', 1 ]
  25. [ 'b', 2 ]
  26. [ 'c', 3 ]
  27. */

time 42m
其实这种写法是没有必要的,因为这是个数据,传数据时尽量用map,考虑到数据的唯一性,用map,数据用map,这是个趋势
for of很常用
迭代器是一个线性的处理方式

image.png
这些都用的迭代器

迭代器部署
可以部署return、throw,除了next

image.png
for of中断,比如break都会执行return方法

generator

time 51m24s

  1. /*这两个写法都可以的*/
  2. // function *test() {
  3. function * test() {
  4. }
  5. let iter=test();
  6. console.log(iter);

image.png

需要与yield结合起来

time 54m53s
这是个迭代器,可以迭代abcd

  1. /*这两个写法都可以的*/
  2. // function *test() {
  3. function * test() {
  4. yield 'a';
  5. yield 'b';
  6. yield 'c';
  7. yield 'd';
  8. }
  9. let iter=test();
  10. console.log(iter.next());
  11. /*{ value: 'a', done: false }*/

time 58m20s

  1. function * test() {
  2. yield 'a';
  3. console.log(1);
  4. yield 'b';
  5. yield 'c';
  6. yield 'd';
  7. }
  8. /*返回值 是迭代器对象;yield产出,暂停函数运行;*/
  9. let iter=test();
  10. console.log(iter.next());
  11. /*{ value: 'a', done: false }*/
  12. /*1不会打印的*/

time 59m23s

  1. function * test() {
  2. yield 'a';
  3. console.log(1);
  4. yield 'b';
  5. yield 'c';
  6. yield 'd';
  7. }
  8. /*返回值 是迭代器对象;yield产出,暂停函数运行;*/
  9. let iter=test();
  10. console.log(iter.next());
  11. console.log(iter.next());
  12. /*{ value: 'a', done: false }
  13. 1
  14. { value: 'b', done: false }
  15. */
  16. /*可以打印之后的,通过继续next*/

应用方式

time 1h4m33s
与赋值结合,与异步结合
这是一种状态,现在不理解没有关系,之后从例子来理解

  1. function * test() {
  2. let value= yield 'a';
  3. console.log(1);
  4. yield 'b';
  5. yield 'c';
  6. yield 'd';
  7. }

yield与return的区别

time 1h6m47s
image.png

image.png
yield与return区别,return的done是true,yield反之,这是表面区别
本质区别
image.png

yield特性

time 1h15m26s

yield返回值

  1. function * test() {
  2. let a= yield 'a';
  3. console.log(a);
  4. yield 'b';
  5. yield 'c';
  6. return 'd';
  7. }
  8. /*yield并不产生值,undefined*/
  9. let iter=test();
  10. console.log(iter.next());
  11. console.log(iter.next());

image.png

这样就变成10了,next传值,yield接收

  1. function* test() {
  2. let a = yield 'a';
  3. console.log(a);
  4. yield 'b';
  5. yield 'c';
  6. return 'd';
  7. }
  8. /*yield并不产生值,undefined*/
  9. let iter = test();
  10. console.log(iter.next());
  11. console.log(iter.next(10));

image.png

time 1h16m55s
yield是个表达式,不能解析成字符串
image.png

  1. function * demo() {
  2. console.log('hello'+yield );
  3. /*SyntaxError: Unexpected identifier*/
  4. }
  5. let iter=demo();
  6. console.log(iter.next());
  1. function * demo() {
  2. console.log('hello'+(yield) );
  3. /*可以通过()把其变成表达式*/
  4. }
  5. let iter=demo();
  6. console.log(iter.next());
  7. /*{ value: undefined, done: false }*/

yield与参数

time 1h23m3s
可以作为参数

  1. function* demo() {
  2. foo(yield 'a', yield 'b');
  3. }
  4. function foo(a, b) {
  5. console.log(a,b)
  6. }
  7. let iter=demo();
  8. console.log(iter.next())
  9. console.log(iter.next())
  10. console.log(iter.next())
  11. /*{ value: 'a', done: false }
  12. { value: 'b', done: false }
  13. undefined undefined
  14. { value: undefined, done: true }
  15. */

time 1h25m34s
yield每次都可以暂停函数,可以通过for of迭代

  1. function * foo(){
  2. yield 1;
  3. yield 2;
  4. yield 3;
  5. yield 4;
  6. yield 5;
  7. yield 6;
  8. }
  9. for (let i of foo()) {
  10. console.log(i);
  11. }
  12. /*打印123456*/
  1. function * foo(){
  2. yield 1;
  3. yield 2;
  4. yield 3;
  5. yield 4;
  6. yield 5;
  7. yield 6;
  8. return 7;
  9. }
  10. for (let i of foo()) {
  11. console.log(i);
  12. }
  13. /*打印123456
  14. * 不会打印7,return的不会被遍历*/

time 1h29m47s

  1. function* foo() {
  2. let value1 = yield 1;
  3. console.log(value1);
  4. let value2 = yield 2;
  5. console.log(value2);
  6. let value3 = yield 3;
  7. console.log(value3);
  8. let value4 = yield 4;
  9. console.log(value4);
  10. }
  11. let iter = foo();
  12. console.log(iter.next());
  13. console.log('-------')
  14. console.log(iter.next());
  15. console.log('-------')
  16. console.log(iter.next());
  17. console.log('-------')
  18. console.log(iter.next());

image.png

解析

  1. function* foo() {
  2. let value1 = yield 1;
  3. console.log(value1);
  4. let value2 = yield 2;
  5. console.log(value2);
  6. let value3 = yield 3;
  7. console.log(value3);
  8. let value4 = yield 4;
  9. console.log(value4);
  10. }
  11. let iter = foo();
  12. /*第一个运行,到yield 1暂停,不走下面的console,所以打印的只有
  13. * console.log(iter.next())的iter.next()*/
  14. console.log(iter.next());
  15. console.log('-------')
  16. /*.next函数继续运行,运行到yield 2,途中有console代码
  17. * 但yield不产生值,所以是undefined*/
  18. console.log(iter.next());
  19. console.log('-------')
  20. /*之后依次类推*/
  21. console.log(iter.next());
  22. console.log('-------')
  23. console.log(iter.next());

time 1h30m
next传值

  1. function* foo() {
  2. /*第一次的值拿不到,只能拿到第二次的值,报错未定义value1*/
  3. // console.log('value1:' + value1);
  4. let value1 = yield 1;
  5. console.log('value1:' + value1);
  6. let value2 = yield 2;
  7. console.log('value2:' + value2);
  8. let value3 = yield 3;
  9. console.log('value3:' + value3);
  10. let value4 = yield 4;
  11. console.log('value4:' + value4);
  12. }
  13. let iter = foo();
  14. console.log(iter.next('one'));
  15. console.log('-------')
  16. /*打印的是第二个two,因为value1是在第二次next才给它赋值
  17. * 第一次只运行了yield 1操作,没有运行赋值操作*/
  18. console.log(iter.next('two'));
  19. console.log('-------')
  20. console.log(iter.next('three'));
  21. console.log('-------')
  22. console.log(iter.next('four'));
  23. console.log(iter.next('five'));

image.png

蛇形传值
image.png

yeild重写迭代器

time 1h39m
image.png

time 1h43m51s
改写之前的map抽取
image.png

应用:读取文件

time 45m
上节课内容复习
image.png

image.png
image.png
time 1h53m

  1. const fs = require('fs');
  2. function promsiify(fn) {
  3. return function (...args) {
  4. return new Promise((resolve, reject) => {
  5. fn(...args, (err, data) => {
  6. if (err) {
  7. reject(err);
  8. } else {
  9. resolve(data);
  10. }
  11. })
  12. })
  13. }
  14. }
  15. let readFile = promsiify(fs.readFile);
  16. readFile('./name.txt', 'utf-8')
  17. .then(res => readFile(res, 'utf-8'))
  18. .then(res => readFile(res, 'utf-8'))
  19. .then(res => console.log(res))
  20. /*99*/

time 1h53m 2h0mW
希望有个方法可以读取异步操作

  1. const fs = require('fs');
  2. function promsiify(fn) {
  3. return function (...args) {
  4. return new Promise((resolve, reject) => {
  5. fn(...args, (err, data) => {
  6. if (err) {
  7. reject(err);
  8. } else {
  9. resolve(data);
  10. }
  11. })
  12. })
  13. }
  14. }
  15. let readFile = promsiify(fs.readFile);
  16. readFile('./name.txt', 'utf-8')
  17. /* .then(res => readFile(res, 'utf-8'))
  18. .then(res => readFile(res, 'utf-8'))
  19. .then(res => console.log(res))*/
  20. function* read() {
  21. let value1 = yield readFile('./name.txt', 'utf-8');
  22. let value2 = yield readFile(value1, 'utf-8');
  23. let value3 = yield readFile(value2, 'utf-8');
  24. console.log(value3)
  25. }
  26. let iter = read();
  27. // let a = iter.next();
  28. // let {value:xx,done=false}=iter.next();
  29. /*value是个promise*/
  30. let {value,done}=iter.next();
  31. value.then((val)=>{
  32. console.log(val);
  33. })
  34. /*./number.txt*/

time 2h12m

  1. const fs = require('fs');
  2. function promsiify(fn) {
  3. return function (...args) {
  4. return new Promise((resolve, reject) => {
  5. fn(...args, (err, data) => {
  6. if (err) {
  7. reject(err);
  8. } else {
  9. resolve(data);
  10. }
  11. })
  12. })
  13. }
  14. }
  15. let readFile = promsiify(fs.readFile);
  16. readFile('./name.txt', 'utf-8')
  17. /* .then(res => readFile(res, 'utf-8'))
  18. .then(res => readFile(res, 'utf-8'))
  19. .then(res => console.log(res))*/
  20. function* read() {
  21. let value1 = yield readFile('./name.txt', 'utf-8');
  22. let value2 = yield readFile(value1, 'utf-8');
  23. let value3 = yield readFile(value2, 'utf-8');
  24. console.log(value3)
  25. }
  26. let iter = read();
  27. // let a = iter.next();
  28. // let {value:xx,done=false}=iter.next();
  29. /*value是个promise*/
  30. let {value, done} = iter.next();
  31. value.then((val1) => {
  32. // console.log(val);
  33. /*val其实是传的value1,value1的值为val1*/
  34. // iter.next(val1)
  35. let {value, done} = iter.next(val1);
  36. value.then(val2 => {
  37. // console.log(val2)
  38. let {value, done} = iter.next(val2);
  39. value.then(val3 => console.log(val3));//99
  40. })
  41. })

需要自己不看代码,自己实现,需要看录播
现在层层嵌套,还不如之前的方式,需要优化

优化

time 2h15m38s
减少next调用次数

  1. const fs = require('fs');
  2. function promsiify(fn) {
  3. return function (...args) {
  4. return new Promise((resolve, reject) => {
  5. fn(...args, (err, data) => {
  6. if (err) {
  7. reject(err);
  8. } else {
  9. resolve(data);
  10. }
  11. })
  12. })
  13. }
  14. }
  15. let readFile = promsiify(fs.readFile);
  16. readFile('./name.txt', 'utf-8')
  17. /* .then(res => readFile(res, 'utf-8'))
  18. .then(res => readFile(res, 'utf-8'))
  19. .then(res => console.log(res))*/
  20. function * read() {
  21. let value1 = yield readFile('./name.txt', 'utf-8');
  22. let value2 = yield readFile(value1, 'utf-8');
  23. let value3 = yield readFile(value2, 'utf-8');
  24. // console.log(value3)
  25. return value3;
  26. }
  27. // let iter = read();
  28. // let a = iter.next();
  29. // let {value:xx,done=false}=iter.next();
  30. /*value是个promise*/
  31. /*let {value, done} = iter.next();
  32. value.then((val1) => {
  33. // console.log(val);
  34. /!*val其实是传的value1,value1的值为val1*!/
  35. // iter.next(val1)
  36. let {value, done} = iter.next(val1);
  37. value.then(val2 => {
  38. // console.log(val2)
  39. let {value, done} = iter.next(val2);
  40. value.then(val3 => console.log(val3));//99
  41. })
  42. })*/
  43. /*./number.txt*/
  44. function Co(iter) {
  45. return new Promise((resolve, reject) => {
  46. let next = (data) => {
  47. let {value, done} = iter.next(data);
  48. if (done){
  49. resolve(value)
  50. }else {
  51. value.then((val)=>{
  52. next(val);
  53. })
  54. }
  55. }
  56. next();
  57. })
  58. }
  59. let promise = Co(read())
  60. promise.then((val) => {
  61. console.log(val);
  62. })

time 2h25m
不要求直接就可以写出来,要求先理解它
通过递归实现

安装模块

time 2h26m
npm i co -D

tj

time 2h28m
js大神tj,不是计算机专业出身的,在所有的开源项目中贡献可以说是最大的

image.png

async

time 2h31m
es2017实现了async
tj离开js社区原因之一是js不支持async

async是语法糖

  1. const fs = require('fs');
  2. function promsiify(fn) {
  3. return function (...args) {
  4. return new Promise((resolve, reject) => {
  5. fn(...args, (err, data) => {
  6. if (err) {
  7. reject(err);
  8. } else {
  9. resolve(data);
  10. }
  11. })
  12. })
  13. }
  14. }
  15. let readFile = promsiify(fs.readFile);
  16. readFile('./name.txt', 'utf-8')
  17. /* .then(res => readFile(res, 'utf-8'))
  18. .then(res => readFile(res, 'utf-8'))
  19. .then(res => console.log(res))*/
  20. async function read() {
  21. let value1 = await readFile('./name.txt', 'utf-8');
  22. let value2 = await readFile(value1, 'utf-8');
  23. let value3 = await readFile(value2, 'utf-8');
  24. // console.log(value3)
  25. return value3;
  26. }
  27. function Co(iter) {
  28. return new Promise((resolve, reject) => {
  29. let next = (data) => {
  30. let {value, done} = iter.next(data);
  31. if (done){
  32. resolve(value)
  33. }else {
  34. value.then((val)=>{
  35. next(val);
  36. })
  37. }
  38. }
  39. next();
  40. })
  41. }
  42. let promise = Co(read())
  43. promise.then((val) => {
  44. console.log(val);
  45. })