我想做什么-使用"AWAIT"关键字,这样我就可以在程序结束和挂起之前得到结果。我读了几十个博客,答案如下:
1.使用await关键字,简单
1.使用async(){}换行
1.有人说根本不需要等待。
但这些对我还没起作用。
const redis = require('ioredis');
const REDIS_RELATIX_HOST = "redis-xxxx.c277.us-east-1-3.ec2.cloud.redislabs.com"
const REDIS_RELATIX_PORT = "12269"
const REDIS_RELATIX_PASSWORD = "mypassword"
let result = "dummy";
const redisClient = redis.createClient({
host: REDIS_RELATIX_HOST,
port: REDIS_RELATIX_PORT,
password: REDIS_RELATIX_PASSWORD
})
redisClient.on('error', err => {
console.log('Error ' + err);
});
await getSpanishWordForRed();
Console.Write("result=" + result);
async function getSpanishWordForRed(){
console.log("getSpanishWordForRed:start")
await redisClient.hget('spanish', 'red',
(err, value) => {
if (err) console.log(err);
else {
console.log(value);
result = value.toString();
}
});
console.log("getSpanishWordForRed:end")
}
console.log("The end") // I've tried with and without this line - just for fun.
我看过一些帖子说你可以直接调用async函数,但这就是我得到的。
await getSpanishWordForRed();
^^^^^
SyntaxError: await is only valid in async functions and the top level bodies of modules
这就提出了两个问题:
1.我不是在一个模块里吗?
1.我不是在"最高层机构"吗?
所以我想,如果我把代码分成两个例程,一个是模块,但问题是,我仍然需要在主程序中有"await",不是吗,它不是模块?
我创建了一个主例程:
var mySpanishWord = require('./redisTestNodeOnly8Module.js')
console.log("main before await result");
result = mySpanishWord();
console.log("main result=" + result);
然后我想我创建了一个"模块"(文件名:redisTestNodeOnly 8模块. js):
exports.SpanishWordForRed = async function() {
const redis = require('ioredis');
const REDIS_RELATIX_HOST = "redis-xxxxx.c277.us-east-1-3.ec2.cloud.redislabs.com"
const REDIS_RELATIX_PORT = "12269"
const REDIS_RELATIX_PASSWORD = "mypassword"
const redisClient = redis.createClient({
host: REDIS_RELATIX_HOST,
port: REDIS_RELATIX_PORT,
password: REDIS_RELATIX_PASSWORD
})
redisClient.on('error', err => {
console.log('Error ' + err);
});
let result = "dummy";
console.log("getSpanishWordForRed:start")
await redisClient.hget('spanish', 'red',
(err, value) => {
if (err) console.log(err);
else {
console.log(value);
result = value.toString();
return value.toString();
}
});
}
结果:
c:\GitHub\Relatix\Apps\CMS_Bad2\src>node redisTestNodeOnly8.js
main before await result
getSpanishWordForRed:start
main result=[object Promise]
The end
rojo
^C
这是一个已经很长的问题的简化版:Redis 4.5.1 - hanging in NodeJS 18我想把这个问题限制在"模块"和"顶级"错误的问题上,以及如何解决这个问题。
这是我之前尝试过的东西(redisTestNodeOnly7Module,是的,还有其他六个redis、ioredis的变体,没有一个工作)。
const redis = require('ioredis');
const REDIS_RELATIX_HOST = "redis-xxxxx.c277.us-east-1-3.ec2.cloud.redislabs.com"
const REDIS_RELATIX_PORT = "12269"
const REDIS_RELATIX_PASSWORD = "mypassword"
let result = "dummy";
const redisClient = redis.createClient({
host: REDIS_RELATIX_HOST,
port: REDIS_RELATIX_PORT,
password: REDIS_RELATIX_PASSWORD
})
redisClient.on('error', err => {
console.log('Error ' + err);
});
console.log("before call runRedis()");
// wordPromise = await getSpanishWordForRed();
(async function() {
const wordPromise = await getSpanishWordForRed();
//console.log("after call runRedis() wordPromise=" + wordPromise.toString() );
//console.log("after call runRedis() wordPromise=" + wordPromise.resolve());
console.log("after call runRedis() result=" + result);
})();
async function getSpanishWordForRed(){
console.log("getSpanishWordForRed:start")
await redisClient.hget('spanish', 'red',
(err, value) => {
if (err) console.log(err);
else {
console.log(value);
result = value.toString();
}
});
console.log("getSpanishWordForRed:end")
}
console.log("The end")
结果(仍然显示"结束"之前的理论"等待"发生"):
before call runRedis()
getSpanishWordForRed:start
The end
rojo
getSpanishWordForRed:end
after call runRedis() result=rojo
^C
更新-这是我的"副本"马特的代码,和结果。
我仍然得到"rojo"作为西班牙语单词红色回来,但程序仍然"挂起"。如果我运行"节点program.js",它应该只是结束,并返回到命令提示符正常?我必须点击CNTL-BREAK杀死它。
const redis = require('ioredis');
const REDIS_RELATIX_HOST = "redis-xxxxx.c277.us-east-1-3.ec2.cloud.redislabs.com"
const REDIS_RELATIX_PORT = "12269"
const REDIS_RELATIX_PASSWORD = "mypassword"
let result = "dummy";
const redisClient = redis.createClient({
host: REDIS_RELATIX_HOST,
port: REDIS_RELATIX_PORT,
password: REDIS_RELATIX_PASSWORD
})
redisClient.on('error', err => {
console.log('Error ' + err);
});
redisClient.on('connect', () => {
console.log('Connected to Redis');
});
async function getSpanishWordForRed(){
console.log("getSpanishWordForRed:start")
return redisClient.hget('spanish', 'red')
}
async function go(){
console.log("go():start")
const result = await getSpanishWordForRed()
console.log("go():end result=", result)
// put the rest of the control flow inside go.
}
// Use this as the commonjs entry, so things are `await`able
go().catch(err => {
console.error("go/catch error:" + err)
process.exit(1)
})
console.log("The end")
执行:
c:\Demo\src>node redisTestNodeOnlyStackOverflowMatt.js
go():start
getSpanishWordForRed:start
The end
Connected to Redis
go():end result= rojo
^C
1条答案
按热度按时间xe55xuns1#
错误
await is only valid in async functions and the top level bodies of modules
中的modules
术语指的是ECMAScript module。文件需要使用扩展名.mjs
,或者在package.json
中标记为"type": "module"
并使用import
语法。代码对
await getSpanishWordForRed()
的初始调用是“顶级”的,所以在节点Common JS模块中不起作用,使用require()
语法。CommonJS是可以的,下面的例子详细介绍了一种稍微不同的方式来初始化异步函数调用。对于ioredis,示例代码似乎与文档中的连接API不匹配。可能挂起与缺乏连接有关?
代码还混合了Promise/await API和Callback API,方法是提供一个函数作为最后一个参数,只需使用Promise而不使用回调函数:
使用此入口点将删除顶级等待/模块问题。