node.js - 全局变量在节点中更改后不保留值
问题描述
我的问题是我的代码在 readfile 调用中将 champName 分配给函数内部的不同值。但是,调用结束后,champName 不会保留该值,即使它是为该函数全局声明的。我该如何解决?
下面的代码是我现在所拥有的。以前我尝试在函数外部使用 for 循环,但cannot read property 'length' of undefined
即使 undefined 应该是之前定义的 champsJson,我也会收到错误消息,这意味着 champsJson 不会在该方法之外得到更新。
//This function takes in a champId (number) and returns the appropriate
//string that is associated with that champId
function decipherChamp(champId) {
//Local variables
var champName = 'This should never print';
var champsJson = ''
//Reads champions.json into rawData
fs.readFile('./commands/lol/champions.json', 'utf8', function (err, data) {
if (err)
throw err;
champsJson = JSON.parse(data);
for (let i = 0; i < champsJson.length; i++) {
if (champsJson[i].championId == champId) {
champName = champsJson[i].championName;
console.log("champName inside fn: " + champName)
}
}
});
console.log("champName before return: " + champName)
return champName
}
我console.log("champName before return: " + champName)
在打印之前添加了查看 champName 是什么,它打印This should never print
的是初始化值,而不是预期的结果,<The Champion's Name>
观察到的输出:
Running command lol:currgame.
champName before return: This should never print
champName inside fn: Brand
champName before return: This should never print
champName inside fn: Graves
champName before return: This should never print
champName inside fn: Tristana
champName before return: This should never print
champName inside fn: Jax
champName before return: This should never print
champName inside fn: Malzahar
champName before return: This should never print
champName inside fn: Thresh
champName before return: This should never print
champName inside fn: Galio
champName before return: This should never print
champName inside fn: Kai'Sa
champName before return: This should never print
champName inside fn: Trundle
champName before return: This should never print
champName inside fn: Kennen
预期输出:
Running command lol:currgame.
champName before return: Brand
champName inside fn: Brand
champName before return: Graves
champName inside fn: Graves
champName before return: Tristana
...
我还注意到它在函数结果内部之前的 return 之前打印了 champName,这让我相信这是我对节点中异步的理解的错误,但我不确定。
解决方案
使用fs.readFileSync()
是有效的,但不一定是一个好的解决方案。
Node 中的同步操作(例如文件 I/O)可能会阻塞并以意想不到的方式影响您的应用程序。更好的解决方案是使用
const { promisify } = require('util');
const asyncReadFile = promisify(fs.readFile);
在文件的顶部,并将decipherChamp()
代码更改为以下几行:
async function decipherChamp ( champId )
let champName = `Never see me...`;
let champData;
try {
const file = await asyncReadFile(...);
champData = JSON.parse(file);
}
catch (e) {
console.error(e); // error handling - failed to read file
champName = `FAILED!`; // or whatever when error occurs
}
const champ = champData.find(champ => champ.championId == champId);
if ( champ ) {
champName = champ.champName;
}
console.log(...);
return champName;
}
推荐阅读
- flutter - 运行时颤动“与设备的连接丢失”
- google-apps-script - 如何从谷歌表格中的数据中删除破折号,然后执行 forEach 循环
- html - Qt - 使用网页的 qtNetworkAccesManager 获取所有源代码(HTML 代码)的问题
- python - 如何通过通行证在图形上绘制标签?
- javascript - 请解释这个 Minimax Javascript 代码
- c - C 中不兼容的指针类型 || 无效(*)(无效*)
- reactjs - 功能组件的 props 的默认值有什么问题
- javascript - 我如何在 html 中制作超过 1 个幻灯片画廊?
- java - Java:为什么在使用 Stream+Iterator 时不会发生 ConcurrentModificationException?
- javascript - 如何在 Fetch GET 请求中插入参数?