动作行动立即返回



我试图理解ActionHero async/等待和撞到许多墙壁的核心概念。本质上,在一个动作中,为什么要立即返回,而不是500ms之后?

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

澄清编辑:这个问题更多地是关于异步执行流和承诺实现,而不是settimeout((的字面使用。它并不是真正针对ActionHero的,而是AH使用的模式,是我第一次接触概念。答案提供了澄清,必须将某些功能包裹在诺言中,以便他们可以等待,并且有多种方法可以做到。

因为您没有等待完成。

基本上您需要等待Settimeout。

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

但这无效,因为Settimeout不是承诺

您可以使用一段时间后解决的简单睡眠功能。

async function sleep (time) {
  return new Promise(resolve => setTimeout(resolve, time));
}
async function run (data) {
  await sleep(500);
  data.response.outcome = 'success';
}

就像settimeout一样,这是一个回调API,可以作为承诺,可以将流置于承诺中。注意在睡眠和读取示例中,我只使用异步关键字使事情变得清晰

  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));
    });
  }

对于大多数功能,您可以跳过手动合格并使用util.promisify

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

关键部分是工作应在完成工作后解决,并且您应该使用await.then

等待它。

因此,例如使事情变得更清楚一个示例

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

甚至

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

在运行时都相同

所以要完成

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);
  });
}

最新更新