什么是协程?颠覆传统的代码控制权
协程,简单来说,就是一种可以在中途“挂起”和“恢复”执行的函数。你可以通过代码主动切换任务、让函数暂停、再回来续写流程!在“主流编程神器”Python、Lua里协程早已玩出花样,JS虽然没有原生协程,但却巧妙地用 Generator 和 async/await 实现了这一魔法。
一、Generator:JS世界里的协程利器
function* myCoroutine() {
console.log('Start');
yield 1; // 挂起
console.log('Resume!');
yield 2; // 再次挂起
console.log('Done!');
}
const gen = myCoroutine();
console.log(gen.next()); // Start, {value: 1, done: false}
console.log(gen.next()); // Resume!, {value: 2, done: false}
console.log(gen.next()); // Done!, {value: undefined, done: true}
🚀 亮点解析
function*声明生成器函数。yield可在任意位置挂起,等你想恢复后用.next()传递控制权回来!- 可以像写同步代码一样组织流程,不再被嵌套异步裹挟!
二、协程多任务调度:用 Generator 轮流“工作”!
function* task1() {
yield "任务1-第1步";
yield "任务1-第2步";
}
function* task2() {
yield "任务2-第1步";
yield "任务2-第2步";
}
const t1 = task1();
const t2 = task2();
console.log(t1.next().value); // 任务1-第1步
console.log(t2.next().value); // 任务2-第1步
console.log(t1.next().value); // 任务1-第2步
console.log(t2.next().value); // 任务2-第2步
你甚至可以手动写个“调度器”,同时管理 N 个协程任务,轻松实现“伪并发”!
三、async/await:协程思想的终极落地
async function awesomeAsync() {
console.log("第1步");
await new Promise(res => setTimeout(res, 1000)); // 挂起1秒
console.log("第2步");
}
awesomeAsync();
💡 写点高级用法,玩转协程调度
多任务“公平调度”
function* logger(name, times) {
for (let i = 0; i < times; i++) {
yield `${name}执行到第${i + 1}步`;
}
}
const tasks = [logger("A", 2), logger("B", 2), logger("C", 2)];
while (tasks.length) {
const t = tasks.shift();
const res = t.next();
if (!res.done) {
console.log(res.value);
tasks.push(t);
}
}
// 输出顺序:A1->B1->C1->A2->B2->C2
四、协程难点锦囊
- Generator 需要手动调度,但适合复杂流程、结构更巧妙
- async/await 更好用,无痛切换同步/异步世界,现代主流推荐
五、结语
如果你觉得这篇文章有用,记得点赞、收藏、分享,关注我查看更多前端干货!