迭代器模式与迭代器
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);
})