阅读 573

async,await,来来来了解一下

  • 首先问个问题,一般类数组转化成数组的方式有哪些呢?比如:
1 Array.prototype.slice.call(arrayLike);
2 Array.from(arrayLike);
3 [...arrayLike];
  • 这里要谈到的一个问题就是,关于类数组?
  • 一般的可以认为,一个数组有key,value,length,例如:
let obj = {0:1,1:2,length:2};
复制代码
  • 用以上3种方法,发现第三者会报错
let arr = [...obj];//obj is not iterable
复制代码
  • 说明缺少一个迭代器

1.generator

let obj = {
    0:'1',
    1:'2',
    length:2,
    [Symbol.iterator]:function() {//迭代器
        let index = 0;
        let that = this// 迭代器中的this就是这个对象
        return {//返回的是对象
        	next() {
        		return {
        		    value: that[index],//value代表的是值
        			done: (that.length === index++)?true:false//done代表的是是否迭代完成,true迭代完成
        		}	
        	}
        }
    }
}
复制代码
  • 使用[...obj]时即可直接调用迭代器中的next方法。 一个next方法,里面有value跟done,每调用一次next,执行一次。。。 而生成器函数可以帮我们自动调取。
function *gen(x) {
    let b = yield x; // *跟yield一起使用
    let c= yield b;
    return c
}//每一次yield都会暂停。
console.log(gen('林俊杰').next())//此次执行的是yield x,并且第一次传的参数为x
console.log(gen('王娇').next())//第二次调用next时,把参数赋给b,
//下一次next传递的参数,是上次yield的返回值
复制代码
function *a() {
    yield '1';
    yield '2';
}
function *b(){
    yield '3';
    yield *a();//要想在generator中嵌套,同样需要加×
    yield '4';
}
复制代码
  • 如果上面的例子,结合promise的话,当promise多层嵌套时
let {promisify} = require('bulebird');//让异步方法promise化
let fs =require('fs');
let read = promisify(fs.read);
function *gen() {//模拟先读a.txt,得到里面的内容再赋给b,继续读
    let b = yield read('a.txt','utf8');
    let c = yield read(b,'utf8');
    return c; 
}
let it = gen();//迭代器
it.next().value.then((data)=>{//it.next().value执行yield read('a.txt'),得到promise,继续then,下同
    it.next(data).value.then((data)=>{
        it.next(data);
    })
})
复制代码

2.co

  • co可以用来执行多层嵌套的promise,要求每次yield执行后的是promise(co是node一个包)
let co = require('co');
co(gen()).then(data=>{
    console.log(data);
})
复制代码
  • 下面是手写co
function co(it){
    return new Promise((resolve, reject)=>{
        function next() {//异步递归
            let {value, done} = it.next();//返回值有两个,
            if(!done){//根据done来判断是否走到了return
                value.then((data)=>{
                    next(data);//当第一个promise执行完再继续执行下一个next
                },reject);//只要其中有一个promise失败就失败
            }else {//迭代成功后将成功的结果返回
                resolve(value);
            }
        }
        next();
    })
}
复制代码

3.async,await 是generator的语法糖,相当于generator+co

async function r(){//不必在写generator
    let b = await read('a.txt,'utf8);
    let c = await read(b, 'utf8');
    return c;
}
r().then(data=>{
    console.log(data);
})
console.log(r);//其中async声明的函数都是promise
复制代码
文章分类
前端
文章标签