簡體   English   中英

Javascript Promise 沒有解析

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM