迭代器模式与迭代器
time 8m
迭代器模式,结构化模式:从源 以一次一个的方式抽取;
迭代器是迭代器模式的具体实现,是迭代器模式的一种实现方式
内部迭代器
系统帮我们定义好的
内部迭代器与外部迭代器的区别在于它的实现方式,调用方式是不一样的,一个是通过系统内部的方法进行迭代的,比如for of、for each、array.from等,像这种方式都是调用的系统内部的迭代器接口
外部迭代器是我们自己通过手动的方式来定义的,就像之前上面的代码,自己写的,不是系统内部的
对象抽取
因为对象不是有序的连续的,所以没有办法抽取
time 17m48s
map是有序且连续的
time 19m39s
obj与迭代器
time 39m58s

let obj = {a: 1,b: 2,c: 3,[Symbol.iterator]() {let nextIndex = 0;let map = new Map();for (let [key, value] of Object.entries(this)) {map.set(key, value)}let mapEntries = [...map.entries()];return {next() {return nextIndex < mapEntries.length ?{value: mapEntries[nextIndex++], done: false} :{value: undefined, done: true}}}}}for (let i of obj) {console.log(i);}/*[ 'a', 1 ][ 'b', 2 ][ 'c', 3 ]*/
time 42m
其实这种写法是没有必要的,因为这是个数据,传数据时尽量用map,考虑到数据的唯一性,用map,数据用map,这是个趋势
for of很常用
迭代器是一个线性的处理方式

这些都用的迭代器
迭代器部署
可以部署return、throw,除了next

for of中断,比如break都会执行return方法
generator
time 51m24s
/*这两个写法都可以的*/// function *test() {function * test() {}let iter=test();console.log(iter);

需要与yield结合起来
time 54m53s
这是个迭代器,可以迭代abcd
/*这两个写法都可以的*/// function *test() {function * test() {yield 'a';yield 'b';yield 'c';yield 'd';}let iter=test();console.log(iter.next());/*{ value: 'a', done: false }*/
time 58m20s
function * test() {yield 'a';console.log(1);yield 'b';yield 'c';yield 'd';}/*返回值 是迭代器对象;yield产出,暂停函数运行;*/let iter=test();console.log(iter.next());/*{ value: 'a', done: false }*//*1不会打印的*/
time 59m23s
function * test() {yield 'a';console.log(1);yield 'b';yield 'c';yield 'd';}/*返回值 是迭代器对象;yield产出,暂停函数运行;*/let iter=test();console.log(iter.next());console.log(iter.next());/*{ value: 'a', done: false }1{ value: 'b', done: false }*//*可以打印之后的,通过继续next*/
应用方式
time 1h4m33s
与赋值结合,与异步结合
这是一种状态,现在不理解没有关系,之后从例子来理解
function * test() {let value= yield 'a';console.log(1);yield 'b';yield 'c';yield 'd';}
yield与return的区别
time 1h6m47s

yield与return区别,return的done是true,yield反之,这是表面区别
本质区别
yield特性
time 1h15m26s
yield返回值
function * test() {let a= yield 'a';console.log(a);yield 'b';yield 'c';return 'd';}/*yield并不产生值,undefined*/let iter=test();console.log(iter.next());console.log(iter.next());

这样就变成10了,next传值,yield接收
function* test() {let a = yield 'a';console.log(a);yield 'b';yield 'c';return 'd';}/*yield并不产生值,undefined*/let iter = test();console.log(iter.next());console.log(iter.next(10));

time 1h16m55s
yield是个表达式,不能解析成字符串
function * demo() {console.log('hello'+yield );/*SyntaxError: Unexpected identifier*/}let iter=demo();console.log(iter.next());
function * demo() {console.log('hello'+(yield) );/*可以通过()把其变成表达式*/}let iter=demo();console.log(iter.next());/*{ value: undefined, done: false }*/
yield与参数
time 1h23m3s
可以作为参数
function* demo() {foo(yield 'a', yield 'b');}function foo(a, b) {console.log(a,b)}let iter=demo();console.log(iter.next())console.log(iter.next())console.log(iter.next())/*{ value: 'a', done: false }{ value: 'b', done: false }undefined undefined{ value: undefined, done: true }*/
time 1h25m34s
yield每次都可以暂停函数,可以通过for of迭代
function * foo(){yield 1;yield 2;yield 3;yield 4;yield 5;yield 6;}for (let i of foo()) {console.log(i);}/*打印123456*/
function * foo(){yield 1;yield 2;yield 3;yield 4;yield 5;yield 6;return 7;}for (let i of foo()) {console.log(i);}/*打印123456* 不会打印7,return的不会被遍历*/
time 1h29m47s
function* foo() {let value1 = yield 1;console.log(value1);let value2 = yield 2;console.log(value2);let value3 = yield 3;console.log(value3);let value4 = yield 4;console.log(value4);}let iter = foo();console.log(iter.next());console.log('-------')console.log(iter.next());console.log('-------')console.log(iter.next());console.log('-------')console.log(iter.next());

解析
function* foo() {let value1 = yield 1;console.log(value1);let value2 = yield 2;console.log(value2);let value3 = yield 3;console.log(value3);let value4 = yield 4;console.log(value4);}let iter = foo();/*第一个运行,到yield 1暂停,不走下面的console,所以打印的只有* console.log(iter.next())的iter.next()*/console.log(iter.next());console.log('-------')/*.next函数继续运行,运行到yield 2,途中有console代码* 但yield不产生值,所以是undefined*/console.log(iter.next());console.log('-------')/*之后依次类推*/console.log(iter.next());console.log('-------')console.log(iter.next());
time 1h30m
next传值
function* foo() {/*第一次的值拿不到,只能拿到第二次的值,报错未定义value1*/// console.log('value1:' + value1);let value1 = yield 1;console.log('value1:' + value1);let value2 = yield 2;console.log('value2:' + value2);let value3 = yield 3;console.log('value3:' + value3);let value4 = yield 4;console.log('value4:' + value4);}let iter = foo();console.log(iter.next('one'));console.log('-------')/*打印的是第二个two,因为value1是在第二次next才给它赋值* 第一次只运行了yield 1操作,没有运行赋值操作*/console.log(iter.next('two'));console.log('-------')console.log(iter.next('three'));console.log('-------')console.log(iter.next('four'));console.log(iter.next('five'));

蛇形传值
yeild重写迭代器
time 1h39m
time 1h43m51s
改写之前的map抽取
应用:读取文件
time 45m
上节课内容复习


time 1h53m
const fs = require('fs');function promsiify(fn) {return function (...args) {return new Promise((resolve, reject) => {fn(...args, (err, data) => {if (err) {reject(err);} else {resolve(data);}})})}}let readFile = promsiify(fs.readFile);readFile('./name.txt', 'utf-8').then(res => readFile(res, 'utf-8')).then(res => readFile(res, 'utf-8')).then(res => console.log(res))/*99*/
time 1h53m 2h0mW
希望有个方法可以读取异步操作
const fs = require('fs');function promsiify(fn) {return function (...args) {return new Promise((resolve, reject) => {fn(...args, (err, data) => {if (err) {reject(err);} else {resolve(data);}})})}}let readFile = promsiify(fs.readFile);readFile('./name.txt', 'utf-8')/* .then(res => readFile(res, 'utf-8')).then(res => readFile(res, 'utf-8')).then(res => console.log(res))*/function* read() {let value1 = yield readFile('./name.txt', 'utf-8');let value2 = yield readFile(value1, 'utf-8');let value3 = yield readFile(value2, 'utf-8');console.log(value3)}let iter = read();// let a = iter.next();// let {value:xx,done=false}=iter.next();/*value是个promise*/let {value,done}=iter.next();value.then((val)=>{console.log(val);})/*./number.txt*/
time 2h12m
const fs = require('fs');function promsiify(fn) {return function (...args) {return new Promise((resolve, reject) => {fn(...args, (err, data) => {if (err) {reject(err);} else {resolve(data);}})})}}let readFile = promsiify(fs.readFile);readFile('./name.txt', 'utf-8')/* .then(res => readFile(res, 'utf-8')).then(res => readFile(res, 'utf-8')).then(res => console.log(res))*/function* read() {let value1 = yield readFile('./name.txt', 'utf-8');let value2 = yield readFile(value1, 'utf-8');let value3 = yield readFile(value2, 'utf-8');console.log(value3)}let iter = read();// let a = iter.next();// let {value:xx,done=false}=iter.next();/*value是个promise*/let {value, done} = iter.next();value.then((val1) => {// console.log(val);/*val其实是传的value1,value1的值为val1*/// iter.next(val1)let {value, done} = iter.next(val1);value.then(val2 => {// console.log(val2)let {value, done} = iter.next(val2);value.then(val3 => console.log(val3));//99})})
需要自己不看代码,自己实现,需要看录播
现在层层嵌套,还不如之前的方式,需要优化
优化
time 2h15m38s
减少next调用次数
const fs = require('fs');function promsiify(fn) {return function (...args) {return new Promise((resolve, reject) => {fn(...args, (err, data) => {if (err) {reject(err);} else {resolve(data);}})})}}let readFile = promsiify(fs.readFile);readFile('./name.txt', 'utf-8')/* .then(res => readFile(res, 'utf-8')).then(res => readFile(res, 'utf-8')).then(res => console.log(res))*/function * read() {let value1 = yield readFile('./name.txt', 'utf-8');let value2 = yield readFile(value1, 'utf-8');let value3 = yield readFile(value2, 'utf-8');// console.log(value3)return value3;}// let iter = read();// let a = iter.next();// let {value:xx,done=false}=iter.next();/*value是个promise*//*let {value, done} = iter.next();value.then((val1) => {// console.log(val);/!*val其实是传的value1,value1的值为val1*!/// iter.next(val1)let {value, done} = iter.next(val1);value.then(val2 => {// console.log(val2)let {value, done} = iter.next(val2);value.then(val3 => console.log(val3));//99})})*//*./number.txt*/function Co(iter) {return new Promise((resolve, reject) => {let next = (data) => {let {value, done} = iter.next(data);if (done){resolve(value)}else {value.then((val)=>{next(val);})}}next();})}let promise = Co(read())promise.then((val) => {console.log(val);})
time 2h25m
不要求直接就可以写出来,要求先理解它
通过递归实现
安装模块
time 2h26m
npm i co -D
tj
time 2h28m
js大神tj,不是计算机专业出身的,在所有的开源项目中贡献可以说是最大的

async
time 2h31m
es2017实现了async
tj离开js社区原因之一是js不支持async
async是语法糖
const fs = require('fs');function promsiify(fn) {return function (...args) {return new Promise((resolve, reject) => {fn(...args, (err, data) => {if (err) {reject(err);} else {resolve(data);}})})}}let readFile = promsiify(fs.readFile);readFile('./name.txt', 'utf-8')/* .then(res => readFile(res, 'utf-8')).then(res => readFile(res, 'utf-8')).then(res => console.log(res))*/async function read() {let value1 = await readFile('./name.txt', 'utf-8');let value2 = await readFile(value1, 'utf-8');let value3 = await readFile(value2, 'utf-8');// console.log(value3)return value3;}function Co(iter) {return new Promise((resolve, reject) => {let next = (data) => {let {value, done} = iter.next(data);if (done){resolve(value)}else {value.then((val)=>{next(val);})}}next();})}let promise = Co(read())promise.then((val) => {console.log(val);})
