You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用co.wrap结合生成器?代码输出异常求助

问题分析

你的代码有两个核心问题导致无法得到预期输出:

  1. func1和func2没有返回Promise:co库只能识别并等待Promise、Generator、GeneratorFunction等可等待对象,而你的这两个函数内部是异步的setTimeout,但函数本身没有返回任何异步标识,co无法感知异步操作何时完成,会直接跳过等待继续执行后续代码。
  2. 你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,提问作者김다슬

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:11:15