【问题标题】:Waiting for createWriteStream in KOAJS before exiting在退出之前等待KOAJS中的createWriteStream
【发布时间】:2015-12-16 18:59:48
【问题描述】:

我知道this 的问题,但我的需求有点不同。

我正在尝试下载多张图片,但无法阻止应用在该过程完成之前退出。我已经经历了很多次迭代,这就是我目前所处的位置:

router
.post('/', koaBody(), function *() {
    var images = [];
    //console.log(this.request.body.fields);
    if (this.request.body.fields) {
        images = this.request.body.fields['images'];
        imageCount = images.length;
    } else {
        this.status = 500;
        return;
    }

    var url = 'https://www.google.ca/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png';
    var filepath = '../images/image_1.png';

    var pipeRequest = function (url, filepath) {
        return new Promise(function (resolve, reject) {
            request.get(url)
                .pipe(fs.createWriteStream(filepath))
                .on('finish', function () {
                    console.log('piped');
                });
        });
    };

    co(function*() {
        yield pipeRequest(url, filepath);
    }).then(function () {
        console.log('done co-func');
    }).catch(function (err) {
        return console.error(err);
    });

    console.log('App exiting...');
});

这不是最优雅的代码,但它可以工作,如果我将协同函数包装在一个循环中,我可以下载任意数量的代码(最终目标是让这个 API 接收图像 URL 的 JSON 列表)。但是,我不能做的是将管道的结果返回给调用者,该应用程序将始终在该过程完成之前退出。我认为将函数调用包装在 yield 中会是答案……但不是。

【问题讨论】:

    标签: javascript generator koa


    【解决方案1】:

    当您在生成器函数(Koa 处理程序)中时,您使用yield 等待。

    一般模式是将你的异步逻辑提取到一个返回承诺的函数中,然后在你的路由中产生它。

    您的代码的第一个问题是您从不使用reject 和resolve 来将其转换为完成/错误状态。承诺永远不知道何时结束。让它永远不会将控制权返回给路由,这可能就是您将它嵌套在另一个 co 进程中的原因。

    在这里,我对其进行了修复,以便它在完成时 resolve()s 和在错误时 reject(err)s。注意:产生一个命中 reject(err) 路径的承诺将引发异常 (err),您可以在调用站点尝试/捕获该异常。

    var pipeRequest = function(url, filepath) {
      return new Promise(function(resolve, reject) {
        request.get(url)
          .pipe(fs.createWriteStream(filepath))
          .on('finish', function() { resolve() })
          .on('error', function(err) { reject(err) })
      });
    };
    

    我看到的第二个问题是您在路由中嵌套了一个 co 进程,这将确保该路由永远不会等待其中的 yield。

    Koa 处理程序已经在 co 进程中运行。实施上述解决/拒绝更改后,只需将整个 co 块替换为顶级 yield pipeRequest(url, filepath)。

    【讨论】:

      猜你喜欢
      • 2023-02-17
      • 2014-07-14
      • 2018-03-25
      • 1970-01-01
      • 2010-11-26
      • 2017-05-31
      • 2022-12-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多