动作英雄动作立即返回
Actionhero actions returning immediately
我试图理解 ActionHero 的一个核心概念 async/await 并且碰了很多壁。本质上,在一个动作中,为什么这个 return 立即,而不是 500 毫秒后?
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可以做成promise,streams可以做成promises。请注意,在 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));
});
}
对于大多数函数,您可以跳过手动 promisification 并使用 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);
});
}
我试图理解 ActionHero 的一个核心概念 async/await 并且碰了很多壁。本质上,在一个动作中,为什么这个 return 立即,而不是 500 毫秒后?
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可以做成promise,streams可以做成promises。请注意,在 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));
});
}
对于大多数函数,您可以跳过手动 promisification 并使用 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);
});
}