function s(){
console.log('ss');
}
function * f(){
/*
当 next() 调用时
从头开始执行
直到yield 开始检查后面的表达式
现在是一个函数,那么首先执行函数
当函数执行完毕,有返回值
下面相当于 yield undefined
*/
yield s();
}
//生成器对象
let g = f();
//开始执行
console.log(g.next());//{value: undefined, done: false}
生成器配合使用Promise
第一步
yield 可以把返回值传递出去,由next()来接受
function do_it(arg){
return new Promise((r , j ) =>{
setTimeout(() => {
r(arg);
}, 1000);
});
}
function * f(){
//yield new Promise(...)
yield do_it('第一步');
}
let g = f();
// res :{value: Promise, done: false}
// res.value 是 yield 传回来的Promise
let res = g.next();
res.value.then(res=>{
//第一步
console.log(res);
});
第二步
next(参数) 可以把参数传递给yield,让yield恢复执行
function do_it(arg){
return new Promise((r , j ) =>{
setTimeout(() => {
r(arg);
}, 1000);
});
}
function * f(){
/*
yield Promise
并暂停流程
*/
let res = yield do_it('第一步');
//第一次: 第一步
console.log('第一次:',res);
// yield 第二个 Promise, 同时暂停执行
res = yield do_it(res + ' 第二步');
}
let g = f();
// next 获得 yield 的第一个Promise
let res = g.next();
res.value.then(res=>{
/*
等第一个Promise执行完后
next将第一个Promise的结果传递进去
并获得第二个Promise
*/
let r = g.next(res);
// 第二个Promise
r.value.then(res=>{
//第一步 第二步
console.log(res);
});
});
第三步,改良上面的代码
上面代码中都需要自己手写then,再调用next()来执行,其代码结构是一致的
利用递归自动完成
function do_it(arg){
return new Promise((r , j ) =>{
setTimeout(() => {
r(arg);
}, 1000);
});
}
function * f(){
let res = yield do_it('第一步');
console.log(res); //第一步
res = yield do_it(res + ' 第二步');
console.log(res); //第一步 第二步
res = yield do_it(res + ' 第三步');
console.log(res); //第一步 第二步 第三步
}
//使用递归来自动化完成
function auto_run(g){
function run(arg){
let result = g.next(arg);
if(result.done)
return;
result.value.then(res=>{
run(res);
});
}
run();
}
auto_run(f());
进化到async await
使用async await来简化上面操作
可先看后面的async await的使用
function do_it(arg){
return new Promise((r , j ) =>{
setTimeout(() => {
r(arg);
}, 1000);
});
}
// 异步迭代器 async function *
async function* f(){
let res = await do_it('第一步');
console.log(res);
res = await do_it(res + ' 第二步');
console.log(res);
res = await do_it(res + ' 第三步');
console.log(res);
}
(async ()=>{
let g = f();
let r = await g.next(); //一直迭代到{done:true}时
console.log('awwait:',r);
})();
async
async 返回一个Promise
async function f(){
//return Promise.resolve(123);
return 123;
}
let pr = f();
pr.then(res=>{
console.log(res); //123
});
如果函数内部有异常则返回一个Promise.reject();
async function f(){
throw new Error('error');
}
let pr = f();
//增加一个 rejected 回调
pr.then(null,res=>{
console.log(res); //error
});
async声明的函数
以下两者等价
async function f(){
return 123;
}
function ff(){
return new Promise((resolve, reject )=>{
try{
resolve(123);
}catch(e){
reject(e);
}
});
}
await
await后跟一个表达式,需要在async声明的函数中使用
yield的增强版, await将先执行表达式,再暂停流程
yield需要手动调用next()执行下一步, await全自动
await将创建一个Promise : 使用Promise.resolve()
简单理解就是使用then
async function f(){
// await Promise.resolve(3);
let res = await 3;
console.log(res); //3
}
f();
await 做了什么
async function f(){
let result = await 3;
}
//相当于
async function f(){
Promise.resolve(3).then(res=>{
let result = res;
});
}
如果await 后面的表达式是一个Promise
//用于返回一个Promise
function test(){
return new Promise((resolve , reject)=>{
resolve(1);
});
}
async function f(){
let result = await test();
}
await相当于
function ff(){
//执行此函数,返回一个Promise
let ret = test();
/*
await创建一个Promise
使用resolve把test()返回值传入
*/
let await_new_promise = new Promise((resolve,reject)=>{
/*
resolve的调用时机在: ret 中的 resolve/reject 调用后
let res = ret.resolve(1);
resolve(res);
*/
resolve(ret);
});
// 使用then添加注册函数来获取值
await_new_promise.then(res=>{
// 相当于 let result = await test();
let result = res;
console.log(res); //1
});
}
await的yield特性体现在哪里
把上面的代码稍作修改
把await的代码放入一个生成器中,加入yield
外部代码就能使用 .next() 来控制流程
function * gen(){
//先调用test(),返回的是一个Promise
let ret = test();
//创建一个Promise
let await_new_promise = new Promise((await_resolve, await_reject)=>{
//使用Promise.resolve来处理结果
await_resolve(ret);
});
// 传递一个Promise
yield await_new_promise;
}
async await 整体实现
根据上面所知 async 声明的函数将返回一个Promise
await将创建一个Promise,并使用then来获取值
await是增强版的yield,可暂停流程,也就是使用生成器来控制流程
有如下代码
function test(){
return new Promise((resolve , reject)=>{
resolve(1);
});
}
async function f(){
let result = await test();
}
异步函数 f 的完整实现
function ff(){
// async 声明的函数将返回一个Promise
return new Promise((r , j)=>{
//await 做的事
function * gen(){
let ret = test();
let await_new_promise = new Promise((await_resolve, await_reject)=>{
await_resolve(ret);
});
yield await_new_promise;
}
// 外部控制流程
try {
// 第一个 await
let g = gen();
//next返回一个对象{done:true/false,value:yield后跟的值}
let obj = g.next();
//获取Promise
let first_await = obj.value;
//最终结果
let result = undefined;
//then中添加fulfilled对应回调来获取结果
first_await.then(res=>{
result = res;
console.log(res); // 1
});
r(result);
} catch (error) {
j(error);
}
});
}
ff();
与生成器代码比较
function do_it(arg){
return new Promise((r , j ) =>{
setTimeout(() => {
r(arg);
}, 1000);
});
}
// 生成器
function * f(){
let res = yield do_it('第一步');
console.log(res); //第一步
res = yield do_it(res + ' 第二步');
console.log(res); //第一步 第二步
res = yield do_it(res + ' 第三步');
console.log(res); //第一步 第二步 第三步
}
/*
生成器需要自己手动调用
或者写递归函数来自动调用
let g = f();
let res = g.next();
res.value.then(res=>{
g.next(res);
....
g.next()...
});
*/
//------------------------------------------------
/*
使用async await
全自动
*/
async function ff(){
let res = await do_it(1);
res = await do_it(res+1);
res = await do_it(res+1);
console.log('res:',res); // 3
}
ff();