node.js - 在我的代码中读取和写入文件是非阻塞的。为什么?
问题描述
我正在开发一个用于 Twitch Song Requests 的机器人。该机器人将阅读 Twitch 聊天,搜索 !sr 命令并获取歌曲名称。然后,它将在 Spotify 中搜索歌曲,获取歌曲的 URI 并将其添加到流媒体的播放列表中。
编辑:如果有任何“愚蠢”的代码问题(如回调@ippi 通知),我很抱歉,我真的是编程新手,尤其是 Node JS。
我现在有两个功能:一个是搜索歌曲并将接收到的 URI 写入文本文件,另一个是从文件中获取 URI。这是代码:
主要代码(两个函数的调用):
testSong(commandName, accessToken);
let uri = getUri();
console.log(uri);
搜索歌曲:
function testSong(song, accessToken) {
let song1;
let song2;
song1 = song.replace("!sr", "");
song2 = song1.trim();
var uri = "";
axios.get('https://api.spotify.com/v1/search?q=' + encodeURIComponent(song2) + '&type=track&market=CH&limit=1', {
headers: {
Authorization: 'Bearer ' + accessToken
}
})
// handle success
.then(function (response) {
uri = response.data.tracks.items[0].uri;
console.log("yeet")
fs.writeFileSync('conf/uri.txt');
logger.log('info', 'Successfully obtained URI for track ' + song2);
})
// handle error
.catch(function (error) {
logger.log('error', 'Error while accessing Spotify.');
return error;
});
}
获取 URI:
function getUri() {
try {
return fs.readFileSync('conf/uri.txt', 'utf-8');
} catch (e) {
logger.log('error', 'Error while reading the URI text file: ' + e.stack);
}
}
我在阅读时遇到了问题。首次运行机器人时,uri.txt 文件为空。
当我在 Twitch 聊天中发送第一个 !sr 时,这首歌没有添加到 Spotify 播放列表中,因为在 getUri 函数读取文件之后,testSong 命令似乎正在写入文本文件。
即使在那之后,我也必须发送一个新的 !sr 来添加第一首歌曲,所以每个请求都会被转移。
知道为什么会这样吗?
我读过异步函数,但据我了解,这不是我想要的,因为我希望在写入文本文件时阻止程序的执行,因此 getUri 函数可以读取当前请求的歌曲 URI,并且不会被移动。
编辑2:正如菲利克斯所说,我修改了代码如下:
testSong(commandName, accessToken).then(() => console.log(getUri()));
function testSong(song, accessToken) {
let song1;
let song2;
song1 = song.replace("!sr", "");
song2 = song1.trim();
var uri = "";
return axios.get('https://api.spotify.com/v1/search?q=' + encodeURIComponent(song2) + '&type=track&market=CH&limit=1', {
headers: {
Authorization: 'Bearer ' + accessToken
}
})
// handle success
.then(function (response) {
uri = response.data.tracks.items[0].uri;
console.log("yeet")
fs.writeFileSync('conf/uri.txt', uri, function (err) {
if (err) {
return console.log(err);
} else {
response = true;
}
});
logger.log('info', 'Successfully obtained URI for track ' + song2);
})
// handle error
.catch(function (error) {
logger.log('error', 'Error while accessing Spotify.');
return error;
});
}
那是对的吗?
解决方案
正如我在评论中已经提到的那样,您遇到此问题是因为您使用的是 Promise,即文件将在您尝试阅读之后的某个时间写入。
正如我们所讨论的,根本不需要使用文件来“传输”值。您可以从testSong
(包装在承诺中)返回值:
function testSong(song, accessToken) {
song = song.replace("!sr", "").trim();
return axios.get('https://api.spotify.com/v1/search?q=' + encodeURIComponent(song2) + '&type=track&market=CH&limit=1', {
headers: {
Authorization: 'Bearer ' + accessToken
}
})
// handle success
.then(function (response) {
return response.data.tracks.items[0].uri;
});
// errors should probably be handled by the caller
}
进而:
testSong(commandName, accessToken)
.then(function(uri) {
console.log(uri);
})
.catch(function(error) {
// handle error
});
async
函数使处理 Promise 变得更容易一些。所以你也可以实现testSong
为
async function testSong(song, accessToken) {
song = song.replace("!sr", "").trim();
const response = await axios.get('https://api.spotify.com/v1/search?q=' + encodeURIComponent(song2) + '&type=track&market=CH&limit=1', {
// ^^^^^
headers: {
Authorization: 'Bearer ' + accessToken
}
});
return response.data.tracks.items[0].uri.
}
推荐阅读
- python - 从 Python 中的 Selenium 输出中获取 URL
- qt - Qt5-QML:如何在点击事件后处理按钮颜色和文本的变化
- amazon-web-services - EC2 Auto Scaling 实例在使用 CodeDeploy 时立即启动和终止
- nginx - Nginx - 有一个主代理,将请求代理到其他两个 Nginx
- github - GitHub GraphQL:获取特定存储库的所有分支
- r - 如何使用 xts 对象列表,如 R 中的 3d 数组?
- mongodb - Solr Mongo/DocDB 增量导入查询不起作用
- python - python中mysql的row_factory替代品
- c# - Action 变量引用的对象,被调用的方法或被调用方法的返回值,也是 Action
- java - Netbeans 11:Java 项目中的多个源