一、iterator:
基于有序连续的数据结构对象。
迭代器的实现:
1、迭代函数返回一个包含next方法的对象;
2、next方法返回一个包含value和done属性的对象
function setIterator(arr){
var index=0
return {
next(){
var obj={}
if(index>arr.length){
return {value:undefined,done:true}
}else{
return {value:arr[index++],done:false}
}
}
}
}
var it=setIterator([1,3,4,5])
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
对象实现迭代器:
var obj = {
a: 1,
b: 2,
c: 3,
['gg'](){
},
[Symbol.iterator]:function(){
var index = 0,
entries = Object.entries(this);
len=entries.length-1;
console.log(len,entries);
return {
next() {
var obj = {}
if (index > len) {
return { value: undefined, done: true }
} else {
return { value: entries[index++], done: false }
}
}
}
}
}
for (let s of obj) {
console.log(s);
}
等价于:
var obj = {
a: 1,
b: 2,
c: 3,
['gg'](){
}}
for (let s of Object.entries(obj)) {
console.log(s);
}
隐式调用[Symbol.iterator]方法操作: 1、拓展运算符(...)
2、map set
3、for ...of Array.from
4、Promise.all / Promise.race
5、yield
二、generator生成器 ,
生成器函数:
返回值:生成器对象,
作用:阻止同步执行
yield:产出不同的内部值,然后暂停函数执行,并且记住上次执行的暂停点
function * test(){
yield 'a'
yield 'b'
yield 'c'
}
let iter=test()
console.log(iter);
console.log(iter.next());
2-2,生成器函数的特点
1、通过返回的生成器调用next方法驱动执行,test内部的语句并不执行
function* test() {
console.log('qige');
console.log('wuzai');
}
let iter = test()
1、yield只能在生成器中使用,报语法错误:
function test(){
yield 'a'
}
2、在生成器内部,不能做赋值操作或者当实参,变量收不到值
function * test(){
var value=yield 'a'
console.log(value);//undefined
foo(yield 'a')
yield 'b'
}
function foo(a) {
console.log(a);
}
let iter = test()
4、yield在表达式中不能单独存在,报语法错误:
function* test() {
var value='qige'+ yield
// var value='qige'+ (yield 'wuzai')
}
通过next传值:
function * test(){
var a=yield 'a' +doo()
console.log(a);
var b=yield 'b'
console.log(b);
}
function doo(){
return 111;
}
var iter=test()
console.log(iter.next());//a111
console.log(iter.next(11));//bb
console.log(iter.next(12));//undefined
通过上面的代码可以知道yield停止在赋值操作之前。
实现Promise
const PENDING = 'pending';
const Fulfilled = 'fulFilled';
const REJECTED = 'rejected';
export default class myPromise {
constructor(executor) {
this.status = PENDING;
this.reason = undefined;
this.value = undefined;
this.fulFilledCallback = () => {};
this.rejectedCallback = () => {};
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e)
}
}
resolve = (res) => {
if (this.status === PENDING) {
this.status = Fulfilled;
this.value = res;
this.fulFilledCallback()
}
}
reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
this.rejectedCallback();
}
}
static resolve(res) {
return new myPromise((resovle, reject) => {
resovle(res)
})
}
static reject(res) {
return new myPromise((resovle, reject) => {
reject(res)
})
}
catch (res) {
return this.then(null, res)
}
then(onFulFilled, onRejected) {
onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : data => data;
onRejected = typeof onRejected === 'function' ? onRejected : err => {
throw err
};
let promise2 = new myPromise((resovle, reject) => {
if (this.status === Fulfilled) {
setTimeout(() => {
let x = onFulFilled(this.value)
resolvePromise(promise2, x)
})
}
if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason)
resolvePromise(promise2, x)
} catch (e) {
reject(e)
}
})
}
if (this.status === PENDING) {
this.fulFilledCallback = () => {
let x = onFulFilled(this.value)
resolvePromise(promise2, x)
}
this.rejectedCallback = () => {
let x = onRejected(this.reason)
resolvePromise(promise2, x)
}
}
})
return promise2;
}
}
function resolvePromise(promise2, x) {
if (x instanceof myPromise) {
let then = x.then;
then.call(x, value => {
setTimeout(() => {
let v = getValueK(value);
resolvePromise(promise2, v)
})
}, err => {
promise2.reject(err)
})
} else {
promise2.resolve(x)
}
}
function getValueK(promise) {
if (promise instanceof myPromise) {
getValueK(promise.value)
} else {
return promise
}
}