简体   繁体   English

Actionhero动作立即返回

[英]Actionhero actions returning immediately

I'm trying to understand a core concept of ActionHero async/await and hitting lots of walls. 我试图了解ActionHero异步/等待的核心概念,并且碰壁很多。 Essentially, in an action, why does this return immediately, rather than 500ms later? 本质上,在一个动作中,为什么返回立即返回,而不是在500ms之后返回?

async run (data) {
  setTimeout(() => data.response.outcome = 'success',500)
}

Clarifying edit: this question was more about async execution flow and promise fulfillment than about the literal use of setTimeout(). 澄清编辑:这个问题更多的是关于异步执行流和承诺实现,而不是setTimeout()的字面使用。 Its not really specific to ActionHero but that's the pattern AH uses and was my first exposure to the concepts. 它并不是真的专用于ActionHero,而是AH使用的模式,这是我第一次接触这些概念。 The answer provided clarifies that some functions have to be wrapped in a promise so they can be await-ed and that there are multiple ways to do that. 提供的答案阐明了某些功能必须包装在一个Promise中,以便可以等待它们,并且有多种方法可以做到这一点。

Because you didn't wait for it to finish. 因为您没有等待它完成。

basically you need to await the setTimeout. 基本上,您需要等待setTimeout。

async run (data) {
  await setTimeout(() => data.response.outcome = 'success',500)
}

but that doesn't work because setTimeout is not a promise 但这不起作用,因为setTimeout不是一个承诺

You can use a simple sleep function that resolves after a time. 您可以使用一个简单的睡眠功能,该功能会在一段时间后解决。

async function sleep (time) {
  return new Promise(resolve => setTimeout(resolve, time));
}

async function run (data) {
  await sleep(500);
  data.response.outcome = 'success';
}

Just like setTimeout, which is a callback api can be made into a promise, streams can be made into promises. 就像setTimeout(可以作为回调api一样)可以做成promise一样,流也可以做成promise。 Note in both the sleep and readFile examples I'm only using the async keyword to make things clear 请注意在sleep和readFile示例中,我仅使用async关键字来使情况更清楚

  async readFile (file) {
    return new Promise((resolve, reject) => {
      let data = '';
      fs.createReadStream(file)
        .on('data', d => data += d.toString())
        .on('error', reject)
        .on('end', () => resolve(data));
    });
  }

For most functions you can skip the manual promisification and use util.promisify 对于大多数功能,您可以跳过手动承诺,而使用util.promisify

   const { readFile } = require('fs');
   const { promisify } = require('util');

   const readFileAsync = promisify(readFile);

The key part is that the promises should resolve after the work is done, and that you should wait for it using either await or .then 关键部分是承诺应在工作完成后解决,并且您应使用await.then等待它

So for instance to make things clearer the first example 例如,为了使事情更清楚,第一个例子

async function run (data) {
  return sleep(500).then(() => data.response.outcome = 'success';);
}

and even 乃至

function run (data) {
  return sleep(500).then(() => data.response.outcome = 'success';);
}

are all the same at runtime 在运行时都一样

So to finish 所以完成

async function transform (inputFile, targetWidth, targetHeight) {
  return new Promise((resolve, reject) => {
    let transformer = sharp()
      .resize(targetWidth, targetHeight)
      .crop(sharp.strategy.entropy)
      .on('info', { width, height } => console.log(`Image created with dimensions ${height}x${width}`)
      .on('error', reject)
      .on('end', resolve);
    inputFile.pipe(transformer);
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM