如何正确使用co.wrap结合生成器?代码输出异常求助
问题分析
你的代码有两个核心问题导致无法得到预期输出:
func1和func2没有返回Promise:co库只能识别并等待Promise、Generator、GeneratorFunction等可等待对象,而你的这两个函数内部是异步的setTimeout,但函数本身没有返回任何异步标识,co无法感知异步操作何时完成,会直接跳过等待继续执行后续代码。- 你yield的是函数引用而非函数调用结果:
yield func1只是把函数对象交给co,co不会自动执行这个函数,自然不会触发里面的setTimeout逻辑。
修正方案
我们需要把异步函数改成返回Promise的形式,并且在yield时调用函数,让co能正确等待异步操作完成。
修正后的完整代码(基于co库)
const co = require('co'); const func1 = function() { // 返回Promise,在setTimeout完成后resolve return new Promise((resolve) => { setTimeout(() => { console.log('func1'); resolve(); // 通知co:这个异步操作完成了,可以继续了 }, 2000); }); }; const func2 = function() { return new Promise((resolve) => { setTimeout(() => { console.log('func2'); resolve(); }, 2000); }); }; const func3 = function() { console.log('func3'); // 同步函数可以返回普通值,co会自动包装为Promise,也可以显式返回Promise.resolve() return 'func3 result'; }; const gen = co.wrap(function*() { yield func1(); // 调用函数,yield它返回的Promise yield func2(); return yield func3(); }); gen() .then(() => console.log('end'));
更现代的替代方案(用async/await替代co)
现在Node.js已经原生支持async/await,它本质上是Generator+Promise的语法糖,比co库更直观且无需额外依赖:
const func1 = function() { return new Promise((resolve) => { setTimeout(() => { console.log('func1'); resolve(); }, 2000); }); }; const func2 = function() { return new Promise((resolve) => { setTimeout(() => { console.log('func2'); resolve(); }, 2000); }); }; const func3 = function() { console.log('func3'); }; async function run() { await func1(); // 等待func1的异步操作完成 await func2(); // 等待func2的异步操作完成 func3(); console.log('end'); } run();
输出结果
两种方案都会按照你期望的顺序输出:
func1 (等待2秒) func2 (等待2秒) func3 end
内容的提问来源于stack exchange,提问作者김다슬
相关产品推荐
相关产品推荐

