我正在構建一個簡單的NEST api,只是為了學習一些東西。其中有一個服務,它有一個名為“getTestFileAsJSON”的方法。我正試圖為一個博客構建這個api。將會有一些文章,它們是.txt格式的文件。
我正在嘗試編寫一種方法,該方法將讀取所述文本文件并返回JSON作為api,這是最佳實踐中的最佳做法。根據我所讀到的,根據文件的大小(尤其是如果它們是巨大的),流是一個好主意。
我在SO周圍搜索解決方案或更多信息,最后在幾次threads之后決定這樣寫我的方法:
async getTestFileAsJSON() {
const text = { value: '' };
const testFileAsReadableStream = createReadStream(
join(process.cwd(), '/files/test.txt'),
);
const streamToString = async (stream) => {
const chunks = [];
for await (const chunk of stream) {
chunks.push(Buffer.from(chunk));
}
return Buffer.concat(chunks).toString('utf-8');
};
const myText = await streamToString(testFileAsReadableStream);
console.log(myText);
text.value = myText;
return JSON.stringify(text);
}
這就完成了任務,我得到了回應。此方法是異步的。但在我的控制器中,我不等待它。這是否意味著即使我使用了async/await,代碼中也沒有真正的異步發生,所以這就是為什么即使我沒有在控制器中等待,一切都在工作?:
@Get('json-file')
getStreamFile() {
return this.blogService.getTestFileAsJSON();
}
您發布的方法確實使用了異步操作,在與異步操作(如讀取文件流)交互的代碼中使用async/await是正確的。然而,要理解代碼的同步和異步方面之間有一個重要的區別。
在getTestFileAsJSON()方法中,在streamToString()函數中使用wait可以確保在讀取文件流后異步填充myText變量。這意味著異步部分在該方法中得到了正確的處理,即使您沒有在控制器方法中等待它,也可以使它正確工作。
控制器方法getStreamFile()返回一個promise,該promise將解析為此.blogService.getTestFileAsJSON()的結果。這意味著文件流的實際處理和處理是異步的,您的API將在等待文件讀取完成時處理其他請求。因此,即使您沒有在控制器中等待結果,代碼仍然是異步的,請求處理也不會被阻止。
但是,您應該注意,在當前代碼中,您在服務方法中返回的是JSON字符串,而不是JavaScript對象。更好的做法是直接從服務方法返回JSON對象,并讓Nest框架在發送響應時處理到JSON的序列化。
以下是您代碼的修改版本:
在這個修改后的版本中,getTestFileAsJSON()方法返回一個對象,當它作為響應發送時,它將自動序列化為JSON。這更符合Nest.js和RESTAPI中的標準行為。