generator作为一个用来操作异步的状态机, 遇到yield停止, 通过调用next()来继续操作。 今天就用generator来举例两个实际开发中的应用。
1,抽奖
function draw(count) { //抽奖模拟 setTimeout(function(count){ console.log(`还剩余${count}次机会!`); }, 1000); } function generatorDraw(count) { // 生成generator函数 while(count > 0) { count --; yield draw(count); } } let beginDraw = generatorDraw(3); // 这个3一般是从服务端获取 开始调用; const btn = document.createElement('button'); btn.innerText = '抽奖'; btn.addEventListener('click', function(){ beginDraw.next(); })
document.body.addpendChild(btn);
这样通过 每次点击按钮就调用一次next 来实现次数的递减,当然抽奖的逻辑每次都会执行, 当然你也可以在每次执行逻辑的时候, 让按钮禁止点击。这样就更加严谨一点。
2,长轮询
以前的长轮询都是通过定时器来不断的访问给定的接口。 鉴于现在的浏览器对websocket的支持已经很好了,所以大部分都可以直接使用websocket, 但可以通过这个来模拟一下使用generator的思路。
function *ajax() { // 模拟ajax请求 yield new Promise((resolve, reject) => { setTimeout(function () { resolve({code :0}); }, 200) }) } function pull() { let generator = ajax(); let step = generator.next(); step.value.then( res => { if (res.code !== 0) { // 通过获得的数据和前一次的想比较,如果相同就继续轮询,不同的话就输出 setTimeout(function () { console.log(`数据没有更新,继续轮询`); pull(); }, 1000) } else { console.log(res); } }) } pull();