【问题标题】:Cannot compile async code with generators in Typescript无法在 Typescript 中使用生成器编译异步代码
【发布时间】:2017-06-08 05:00:50
【问题描述】:

上下文

  1. 在我进入 Typescript 的过程中,有人建议我不应该在异步代码中进行阻塞调用

  2. 我也在使用生成器,因为它们使目录遍历变得容易并且避免耗尽堆栈空间。

但是,当我将异步代码(在本例中:readdir)与生成器结合使用时,编译器会抱怨 yield 只能在生成器内部使用,这让我认为编译器不是能够一次性组合闭包、生成器和异步代码。

function *yyyymmGenerator(dir: string, props: Props) {
    const fs    = require("fs");
    const yyyy  = props.range.getUTCFullYear().toString();
    const mm    = props.range.getUTCMonth().toString();
    const start = `${yyyy}-${mm}`;

    const files = fs.readdir(dir, function(err, files) {
        for (let i = 0; i < files.length; i++) {
            const file: string = files[i];
            if (file.localeCompare(start) >= 0) {
                const d = `${dir}/${file}`;
                yield file;
            }
        }
    });
}

error TS1163: A 'yield' expression is only allowed in a generator body.

问题

在这种情况下,推荐的最佳做法是什么?

如果我只考虑所有内容同步、阻塞代码但将调用“包装”在 Promise 中,这样可以吗?

【问题讨论】:

标签: node.js asynchronous typescript generator


【解决方案1】:

您可以这样做(在回调中调用next 函数):

const gen = yyyymmGenerator(args);

function callback(err, files) {
   if(err) return gen.throw(err);
   gen.next(files);
   // Print all files returned by the generator
   for(file of gen) {
     console.log(file);
   }
}

function *yyyymmGenerator(dir: string, props: Props) {
   const fs    = require("fs");
   const yyyy  = props.range.getUTCFullYear().toString();
   const mm    = props.range.getUTCMonth().toString();
   const start = `${yyyy}-${mm}`;

   const files = yield fs.readdir(dir, callback);

   for (let i = 0; i < files.length; i++) {
      const file: string = files[i];
      if (file.localeCompare(start) >= 0) {
         const d = `${dir}/${file}`;
         yield file;
      }
   }
}

gen.next(); // Start generator

【讨论】:

  • 我理解您提出的解决方案,我认为原则上可行。但是,我想了解我是否应该(或可以?)将错误消息视为编译器在所涉及范围方面受到限制的证据。或者即使它可以被认为是编译器中的错误。我想提出一个问题,但首先我想了解编译器是否因错误或设计而抱怨。有什么想法吗?
  • 编译器抱怨是因为你在function* 之外使用了yield(在回调中),这是合乎逻辑的,因为当你的异步函数被调用时,生成器的执行不会停止,在你的例如生成器可能会在执行 readdir 的回调之前终止
猜你喜欢
  • 2022-01-16
  • 2017-03-17
  • 2017-11-10
  • 2018-03-29
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-15
相关资源
最近更新 更多