Generator
函数可以暂停函数执行,返回任意表达式的值。这样使得Generator
有多重应用场景。
异步操作的同步化表达
既然可以暂停函数执行,意味着可以把异步操作卸载yield语句里面,等到调用next
方法时再往后执行,这实际上等同于不需要写回调函数了,因为异步操作的后续操作可以放在yield
语句下面,反正要等到next
方法时再执行。
-
Generator
函数可以用于处理异步操作,改写回调函数。
function* loadUi(){
showLoadingScreen();
yield loadUiDataAsynchronously() //原先异步的回调函数放在这
hideLoadingScreen();
}
var loader = loadUi();
//加载UI
loader.next();
//卸载UI
loader.next();
我们可以写成这样来理解
function* loadUi(){
console.log("start");
yield console.log('loading') //原先异步的回调函数放在这
console.log("end");
}
var loader = loadUi();
loader.next()
//start
//loading
loader.next()
//end
↑上面的代码,第一次调用loadUi
函数的时候,函数并不会执行,仅返回一个遍历器,直到第一次调用next
方法,则会显示加载界面,并且异步加载数据。再一次调用next
方法,则会隐藏加载界面,这种写法使得加载界面的逻辑都被封装在一个函数中,按部就班非常清晰。
再看一个模拟ajax异步的操作
function* log(){
var result = yield makeAajax('start');
var resp = result;
console.log(resp)
}
function makeAajax(i){
makeAajaxCall(i)
setTimeout(()=>{it.next(' 模拟异步返回的数据')},3000 )
};
var it = log();
it.next();
//{value: undefined, done: false}
//模拟异步返回的数据
↑上面的log
函数就是通过ajax
操作数据。
- 第一次调用
next
开始异步请求,此时的yield
执行异步请求,而赋值操作中的result
为undefined
。 - 第二次调用
next
是在异步请求的回调中,且传入了成功的参数,(在next
被调用并传入参数的时候,此时的参数不但作为next返回对象的value值,它还将作为上一条yield
的返回值。) 所以此时result
被成功赋值。
可以看到,除了多了一个yield
,几乎与同步操作的写法完全一样。makeAajax
函数中的next
方法必须加上返回的参数。
网友评论