我有一個簡單的后端,它從 POST 請求中獲取一個 js 物件并將其保存到 JSON 檔案中。
app.post('/', (req, res) => {
const form= {name, surname, email, message}; //some object
try {
let forms;
fs.readFile('./files/forms.json', {encoding: 'utf8'}, (err, str) => {
if (err) {
//Handle ENOENT: no such file or directory.
if (error.code !== 'ENOENT') throw error; //If not ENOENT, rethrow.
fs.appendFile('./files/forms.json', '', 'utf8', (err) => {if (err) throw err;});
forms= [];
} else {
forms= JSON.parse(str);
}
forms.push(form);
});
fs.writeFile('./files/forms.json', JSON.stringify(forms), (err) => {if (err) throw err;});
res.end();
} catch (error) {
console.log(error);
res.status(500).send({err: "The message was received but was not saved."});
}
});
我想知道對檔案系統的呼叫是否會阻塞節點的事件回圈,從而阻止它回應其他傳入的請求。如果是這種情況,我應該怎么做才能防止它?
(順便說一句,任何改進我的代碼的建議都非常感謝)
uj5u.com熱心網友回復:
您實際上是在異步使用 fs ,這意味著事件回圈不會被阻塞
如果你使用 `fs.readFileSync` 會阻塞事件回圈
請注意,您的示例不會達到您的預期
由于 fs.readFile 是異步的,所以你提供的回呼會在稍后被呼叫,并且會立即處理當前函式的下一條指令,而不需要等待你的回呼被呼叫
// this will proceed immediately before the fs.readFile callback is called which mean that in your case forms will be undefined
forms.push(form);
// here again writeFile is asynchronous, the callback will be called at a later time
fs.writeFile('./files/forms.json', JSON.stringify(forms), (err) => {if (err) throw err;});
// which means that in any case you will end you response even if there is an error that might be thrown later
res.end();
您可能想要在這里做的是將這部分放在回呼中
app.post('/', (req, res) => {
const form= {name, surname, email, message}; //some object
try {
let forms;
fs.readFile('./files/forms.json', {encoding: 'utf8'}, (err, str) => {
if (err) {
//Handle ENOENT: no such file or directory.
if (error.code !== 'ENOENT') {
res.status(500).send();
return;
}
fs.appendFile('./files/forms.json', JSON.stringify([form]), 'utf8', (err) => {
if (err) {
res.status(500).send();
return;
};
res.status(200).send();
});
return;
}
forms= JSON.parse(str);
forms.push(form);
fs.writeFile('./files/forms.json', JSON.stringify(forms), (err) => {
if (err) {
res.status(500).send(...);
return;
}
res.status(200).send()
});
});
} catch (error) {
console.log(error);
res.status(500).send({err: "The message was received but was not saved."});
}
});
如您所見,所有這些嵌套回呼都非常麻煩,您可以查看 async/await 合成器,它可能更具可讀性
另請注意,您在回呼中拋出的錯誤不會像您預期的那樣傳播,因為回呼不會在同一個堆疊呼叫中運行
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/503950.html
