co模块:是为了简化状态函数的启动过程
ES6提供了co模块,又提供了co方法,用于简化状态函数的启动
当调用了co方法之后,可以通过then方法监听状态的改变
在之前,我们定义三个异步函数,让其一个接一个执行,且第一个任务处理结果传递给第二个任务,第二个任务处理的结果传递给第三个任务
代码如下:
<script>
// 定义三个异步操作
let task1 = () => {
return new Promise((resolve, reject) => {
// 1秒之后打印字符串
setTimeout(() => {
console.log('task1 执行完毕')
resolve('task1');
}, 1000)
})
}
let task2 = () => {
return new Promise((resolve, reject) => {
// 2秒之后打印字符串
setTimeout(() => {
console.log('task2 执行完毕')
// resolve('task2');
reject('task2')
}, 2000)
})
}
let task3 = () => {
return new Promise((resolve, reject) => {
// 3秒之后打印字符串
setTimeout(() => {
console.log('task3 执行完毕')
resolve('task3');
}, 3000)
})
}
// 让三个异步操作,一个接一个的执行,
// 第一个任务处理结果传递给第二个任务,
// 第二个任务处理的结果传递给第三个任务
function *main(result) {
// 执行第一个任务
result = yield task1(result);
console.log(11, result);
// 执行第二个任务
result = yield task2(result);
console.log(22, result);
// 执行第三个任务
result = yield task3(result);
console.log(33, result);
// 返回最终的结果
return result;
}
// 启动程序
let m = main('red');
// 执行第一个任务
// 第一次传递不需要接收参数
m.next().value.then(() => {
// 执行第二个任务
m.next('green').value.then(() => {
// 执行第三个任务
m.next('yellow').value.then((res) => {
console.log('最终的结果', res);
}, () => {
m.next('blue').value.then((res) => {
console.log('最终的结果', res);
})
})
})
})
可以看出,通过next()方法遍历通过then()方法监听,需要一层一层嵌套,于是ES6提供了co模块,又提供了co方法,用于简化状态函数的启动
代码如下
// 通过co方法启动main co(main) // 直接监听最终的结果 .then(res => console.log('最终结果是:', res), err => console.log('执行失败了', err))
实现co方法:
function co(gen) { // 返回一个promise方法 return new Promise((resolve, reject) => { // 执行generator函数 let g = gen(); // 定义递归函数 function myNext(res) { // 定义运行结果 let result; // 为了防止代码出现错误 我们可以将语句放入try catch中 try { result = g.next(res); } catch(e) { // 出现错误程序中断 return reject(e); } // 一旦遍历完成,终止执行 if(result.done) { return resolve(result.value); } // 进入下一项 result.value.then(() => { myNext(result.value); }) .catch(err => console.log(err)) } // 执行next myNext(); }) }