在我的代码中读取和写入文件是非阻塞的。为什么?
Reading and writing to file is non-blocking in my code. Why?
我正在开发用于 Twitch 歌曲请求的机器人。机器人将阅读 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);
}
}
我在阅读时遇到了问题。 运行 第一次使用 bot 时,uri.txt 文件为空。
当我在 Twitch 聊天中发送第一个 !sr 时,歌曲没有添加到 Spotify 播放列表中,因为 testSong 命令似乎正在写入文本文件 AFTER getUri 函数读取文件。
甚至在那之后,我必须发送一个新的 !sr 来添加第一首歌曲,所以每个请求都被转移了。
知道为什么会这样吗?
我读过异步函数,但据我所知,这不是我想要的,因为我希望在写入文本文件时阻止程序的执行,因此getUri 函数可以读取当前请求的歌曲 URI,并且不会被移动。
编辑 2: 正如 Felix 所说,我修改了代码如下:
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;
});
}
对吗?
正如我在评论中已经提到的,你遇到这个问题是因为你使用了承诺,即文件将在未来某个时间写入,在你是尝试阅读。
正如我们所讨论的,根本不需要使用文件来“传输”该值。您可以 return 来自 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
function 使使用 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.
}
我正在开发用于 Twitch 歌曲请求的机器人。机器人将阅读 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);
}
}
我在阅读时遇到了问题。 运行 第一次使用 bot 时,uri.txt 文件为空。
当我在 Twitch 聊天中发送第一个 !sr 时,歌曲没有添加到 Spotify 播放列表中,因为 testSong 命令似乎正在写入文本文件 AFTER getUri 函数读取文件。
甚至在那之后,我必须发送一个新的 !sr 来添加第一首歌曲,所以每个请求都被转移了。
知道为什么会这样吗?
我读过异步函数,但据我所知,这不是我想要的,因为我希望在写入文本文件时阻止程序的执行,因此getUri 函数可以读取当前请求的歌曲 URI,并且不会被移动。
编辑 2: 正如 Felix 所说,我修改了代码如下:
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;
});
}
对吗?
正如我在评论中已经提到的,你遇到这个问题是因为你使用了承诺,即文件将在未来某个时间写入,在你是尝试阅读。
正如我们所讨论的,根本不需要使用文件来“传输”该值。您可以 return 来自 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
function 使使用 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.
}