[英]Javascript Promise doesn't resolve
我創建了一個 function,它返回一個 promise,它決定給我通過 API 發送的數據。它叫做getRequestData()
async function getRequestData(req, res) {
return new Promise((resolve, reject) => {
const data = [];
req
.on("data", (chunk) => {
data.push(chunk);
})
.on("end", () => {
const dataDecoded = Buffer.concat(data).toString();
const parsedData = JSON.parse(dataDecoded);
resolve(parsedData);
})
.on("error", (error) => {
reject(error);
});
});
}
我在兩個地方稱這個為 function。 第一個是我創建新用戶的地方。 getRequestData()
function 在這里運行良好。
async function createUser(req, res) {
try {
const userData = await getRequestData(req, res);
const allRegisteredUsers = await getUsersFromDb();
const users = parseUsersData(allRegisteredUsers)
const userExists = users.find((user) => {
return user.username === userData.username;
});
if (userExists) {
return res.end("User already exists!");
}
users.push(userData);
await writeUsersToDb(users);
res.end(JSON.stringify({
message: "User created successfully",
user: userData
}))
} catch (error) {
console.log(error);
res.statusCode = 400;
return res.end("Error creating a new user!");
}
}
在第二個中,我在 function 中調用 getRequestData,這將在我的數據庫中創建一本新書,但getRequestData()
function 從未在此處解析。
async function createBook(req, res) {
try {
const newBook = await getRequestData(req, res);
console.log(newBook);
res.end("Create new book");
} catch (error) {
res.writeHead(500)
res.end(error);
}
}
在我的 API 測試儀(VSCode 上的 Thunder 客戶端)上調用 createBook function 的任何嘗試都會導致 API 沒有響應。 我在我的代碼周圍添加了console.log
語句,發現我的getRequestData()
function 在createBook()
function 中沒有響應。
請問,誰知道是怎么回事?
有關更多上下文,這是請求處理程序
async function serverListener(req, res) {
try {
res.setHeader("Content-Type", "application/json");
if (req.url === "/user/create" && req.method === "POST") {
await createUser(req, res);
} else if (req.url === "/users") {
await authenticateUser(req, res, ["admin"])
getAllUsers(req, res);
} else if (req.url === "/book" && req.method === "POST") {
await authenticateUser(req, res, ["admin"])
createBook(req, res);
} else if (req.url === "/book" && req.method === "PATCH") {
await authenticateUser(req, res, ["admin"])
updateBook(req, res);
} else if (req.url === "/book" && req.method === "DELETE") {
await authenticateUser(req, res, ["admin"])
deleteBook(req, res);
} else if (req.url === "/book/loan" && req.method === "POST") {
loanOutBook(req, res);
} else if (req.url === "/book/return" && req.method === "POST") {
returnLoanedBook(req, res);
} else {
res.statusCode = 404;
res.end("The route does not exists.")
}
} catch(err) {
console.log(err);
res.statusCode = 500;
res.end(err);
};
}
authenticateUser
function
function authenticateUser(req, res, roles) {
return new Promise(async (resolve, reject) => {
try {
const receivedData = await getRequestData(req, res);
const userLoginData = receivedData.userLogin;
if (!userLoginData) {
return reject("You need to be authenticated to continue");
}
const allRegisteredUsers = await getUsersFromDb();
const users = parseUsersData(allRegisteredUsers);
const userFound = users.find((user) => {
return (
user.username === userLoginData.username &&
user.password === userLoginData.password
);
});
if (userFound && roles.includes(userFound.role)) {
resolve(userFound);
} else if (userFound && !roles.includes(userFound.role)) {
res.statusCode = 401;
reject(
"You don't have the required permission to perform this operation."
);
} else {
res.statusCode = 404;
reject("Your user account doesn't exist! Create a new user.");
}
} catch (error) {
reject(error);
}
});
}
如評論中所述, getRequestData
使用請求主體 stream,因此如果在同一請求上第二次調用它,它將永遠掛起。 您可能應該在所有接受 JSON 有效負載的路由上將其稱為中間件(一個高級 Express 概念,將在下面進一步討論)。
除此之外,代碼中還有大量明顯的反模式。 如果您使用的是 Express,它似乎是基於標簽的,那么您提供的所有代碼都是低級請求處理和路由,Express 已經為您的方便編寫、測試和提供了這些代碼。 事實上,這就是 Express 的全部意義所在——提供body-parser
中間件和簡單的調用,如app.get()
和app.post()
來解析 JSON 有效負載和注冊路由,以及許多其他常見任務。 它會自動為您設置Content-Type
標頭。 使用 Express,您可以將這里幾乎所有的代碼替換為幾行代碼,這樣更容易理解和維護。 一般來說,最好使用提供的高級工具來節省時間、保持代碼整潔並避免錯誤,除非您出於教育目的而重新發明輪子。
另外,我注意到你有很多異步函數沒有await
ed,比如createBook(req, res);
. 這將 function 從異步try
/ catch
錯誤流中取出,並(可能)為可能失敗的操作返回即時成功響應。 這似乎是一種疏忽,應該徹底審查。
我不知道應用程序上下文的 rest,但是,在 function getRequestData
上試試這個:
async function getRequestData(req, res) {
return new Promise((resolve, reject) => {
for await (const data of req ) {
resolve(JSON.parse(data));
}
});
}
然后,如果您發送應用程序存儲庫或其他東西讓我們嘗試運行,那就太好了
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.