node.js - 动作英雄动作立即返回
问题描述
我试图理解 ActionHero async/await 的核心概念并遇到很多问题。本质上,在一个动作中,为什么它会立即返回,而不是 500 毫秒后返回?
async run (data) {
setTimeout(() => data.response.outcome = 'success',500)
}
澄清编辑:这个问题更多的是关于异步执行流程和承诺履行,而不是关于 setTimeout() 的字面使用。它并不是真正特定于 ActionHero,但这是 AH 使用的模式,也是我第一次接触这些概念。提供的答案澄清了某些功能必须包装在一个承诺中,以便它们可以被等待,并且有多种方法可以做到这一点。
解决方案
Because you didn't wait for it to finish.
basically you need to await the setTimeout.
async run (data) {
await setTimeout(() => data.response.outcome = 'success',500)
}
but that doesn't work because setTimeout is not a promise
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. Note in both the sleep and readFile examples I'm only using the async keyword to make things clear
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
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
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);
});
}
推荐阅读
- c# - 我可以在 .NET/C# 中使用 botbuilder-timeout 吗?
- c# - 是否可以从 JSON 响应中获取参数的值
- python - 我在 Python django 代码中遇到错误,当我 RUN python3 manage.py runserver 它引发异常
- c# - 将更新从数据网格查看器传回 sql server
- android - react native run android有错误。解决错误后无法更改配置“:packagename:androidApis”的依赖项
- swift - 如何刷新 Swift 应用程序中的菜单项?
- sql - SSDT 在没有任何更改时删除并重新创建表
- webpack - 构建到检测到更改的目录
- python - 在稀疏 CSC 矩阵(Python)中索引和替换值
- asp.net-mvc - 如何从数据库中获取asp .net中的列表表名称