我的快递电话出了什么问题?我需要一个 ID 数组,但它返回一个空数组

压扁

我猜这个问题是因为我不知道如何有效地使用 async await。我仍然不明白,我一直试图理解多年。叹。

无论如何,这是我的功能:

app.post("/declineTrades", async (request, response) => {
  //---------------------------------------------
  const batch = db.batch();
  const listingID = request.body.listingID;
  const tradeOfferQuery = db
    //---------------------------------------------
    //Get trade offers that contain the item that just sold
    //(therefore it cannot be traded anymore, I need to cancel all existing trade offers that contain the item because this item isn't available anymore)
    //---------------------------------------------
    .collection("tradeOffers")
    .where("status", "==", "pending")
    .where("itemIds", "array-contains", listingID);
  //---------------------------------------------
  //Function that gets all trade offers that contain the ID of the item.
  async function getIdsToDecline() {
    let tempArray = [];
    tradeOfferQuery.get().then((querySnapshot) => {
      querySnapshot.forEach((doc) => {
        //For each trade offer found
        let offerRef = db.collection("tradeOffers").doc(doc.id);
        //Change the status to declined
        batch.update(offerRef, { status: "declined" });
        //Get the data from the trade offer because I want to send an email 
        //to the  who just got their trade offer declined.
        const offerGet = offerRef.get().then((offer) => {
          const offerData = offer.data();
          //Check the items that the receiving person had in this trade offer
          const receiverItemIds = Array.from(
            offerData.receiversItems
              .reduce((set, { itemID }) => set.add(itemID), new Set())
              .values()
          );
          //if the receiver item id's array includes this item that just sold, I know that
          //I can get the sender ID (users can be sender or receiver, so i need to check which person is which)
          if (receiverItemIds.includes(listingID)) {
            tempArray.push(offerData.senderID);
          }
        });
      });
    });
    //With the ID's now pushed, return the tempArray
    return tempArray;
  }
  //---------------------------------------------
  //Call the above function to get the ID's of people that got declined 
  //due to the item no longer being available
  const peopleToDeclineArray = await getIdsToDecline();
  //Update the trade offer objects to declined
  const result = await batch.commit();
  //END
  response.status(201).send({
    success: true,
    result: result,
    idArray: peopleToDeclineArray,
  });
});

我猜我return tempArray在错误的地方?但是我试过把它放在其他地方,它仍然返回一个空数组。我的逻辑在这里正确吗?我需要运行 forEach 循环并在batch.commit发生之前和发送响应之前添加到数组中

TIA 伙计们!

编码员

正如@jabaa他们的评论中指出的那样Promise,您的getIdsToDecline函数中存在错误链接的问题

目前,该函数初始化一个名为 的数组tempArray开始执行交易报价查询,然后返回该数组(当前仍为空),因为该查询尚未完成。

虽然你可以扔在await之前tradeOfferQuery.get(),这不会解决你的问题,因为它只会等待tradeOfferQuery执行和一批充满项,同时还不会等待任何的offerRef.get()呼叫完成填补tempArray

为了解决这个问题,我们需要确保所有的offerRef.get()调用都先完成。要获取所有这些文档,您将使用以下代码获取每个文档,等待所有文档完成,然后提取快照:

const itemsToFetch = [ /* ... */ ];
const getAllItemsPromise = Promise.all(
  itemsToFetch.map(item => item.get())
);

const fetchedItemSnapshots = await getAllItemsPromise;

对于基于查询的文档,您可以将其调整为:

const querySnapshot = /* ... */;

const getSenderDocPromises = [];
querySnapshot.forEach((doc) => {
  const senderID = doc.get("senderID");
  const senderRef = db.collection("users").doc(senderID);

  getSenderDocPromises.push(senderRef.get());
}

const getAllSenderDocPromise = Promise.all(getSenderDocPromises);

const fetchedSenderDataSnapshots = await getAllSenderDocPromise;

然而,这两种方法都不是必需的,因为您使用这些offerRef.get()调用请求的文档已经在您的查询中返回,所以我们甚至不需要在get()这里使用

(doc) => {
  let offerRef = db.collection("tradeOffers").doc(doc.id);
  //Change the status to declined
  batch.update(offerRef, { status: "declined" });
  //Get the data from the trade offer because I want to send an email 
  //to the  who just got their trade offer declined.
  const offerGet = offerRef.get().then((offer) => {
    const offerData = offer.data();
    //Check the items that the receiving person had in this trade offer
    const receiverItemIds = Array.from(
      offerData.receiversItems
        .reduce((set, { itemID }) => set.add(itemID), new Set())
        .values()
    );
    //if the receiver item id's array includes this item that just sold, I know that
    //I can get the sender ID (users can be sender or receiver, so i need to check which person is which)
    if (receiverItemIds.includes(listingID)) {
      tempArray.push(offerData.senderID);
    }
  });
}

可以替换为

(doc) => {
  // Change the status to declined
  batch.update(doc.ref, { status: "declined" });

  // Fetch the IDs of items that the receiving person had in this trade offer
  const receiverItemIds = Array.from(
    doc.get("receiversItems") // <-- this is the efficient form of doc.data().receiversItems
      .reduce((set, { itemID }) => set.add(itemID), new Set())
      .values()
  );

  // If the received item IDs includes the listed item, add the
  // sender's ID to the array
  if (receiverItemIds.includes(listingID)) {
    tempArray.push(doc.get("senderID"));
  }
}

可以简化为

(doc) => {
  //Change the status to declined
  batch.update(doc.ref, { status: "declined" });

  // Check if any items that the receiving person had in this trade offer
  // include the listing ID.
  const receiversItemsHasListingID = doc.get("receiversItems")
    .some(item => item.itemID === listingID);

  // If the listing ID was found, add the sender's ID to the array
  if (receiversItemsHasListingID) {
    tempArray.push(doc.get("senderID"));
  }
}

基于此,getIdsToDecline实际上排队拒绝无效交易并返回受影响的发件人的 ID。与其使用函数外部batchtradeOfferQuery对象使这变得更加不清楚,您应该将它们滚动到函数中并将其从 express 处理程序中拉出。我也会将其重命名为declineInvalidTradesAndReturnAffectedSenders.

async function declineInvalidTradesAndReturnAffectedSenders(listingID) {
  const tradeOfferQuery = db
    .collection("tradeOffers")
    .where("status", "==", "pending")
    .where("itemIds", "array-contains", listingID);

  const batch = db.batch();
  const affectedSenderIDs = [];
  
  const querySnapshot = await tradeOfferQuery.get();

  querySnapshot.forEach((offerDoc) => {
    batch.update(offerDoc.ref, { status: "declined" });

    const receiversItemsHasListingID = offerDoc.get("receiversItems")
      .some(item => item.itemID === listingID);

    if (receiversItemsHasListingID) {
      affectedSenderIDs.push(offerDoc.get("senderID"));
    }
  }

  await batch.commit(); // generally, the return value of this isn't useful

  return affectedSenderIDs;
}

然后这会将您的路由处理程序更改为:

app.post("/declineTrades", async (request, response) => {
  
  const listingID = request.body.listingID;
  
  const peopleToDeclineArray = await declineInvalidTradesAndReturnAffectedSenders(listingID);

  response.status(201).send({
    success: true,
    result: result,
    idArray: peopleToDeclineArray,
  });
});

然后添加适当的错误处理,换出HTTP 201 Createdfor的错误使用HTTP 200 OK,并使用json()代替send(); 你现在得到:

app.post("/declineTrades", async (request, response) => {
  try {
    const listingID = request.body.listingID;
  
    const affectedSenderIDs = await declineInvalidTradesAndReturnAffectedSenders(listingID);

    response.status(200).json({
      success: true,
      idArray: affectedSenderIDs, // consider renaming to affectedSenderIDs
    });
  } catch (error) {
    console.error(`Failed to decline invalid trades for listing ${listingID}`, error);

    if (!response.headersSent) {
      response.status(500).json({
        success: false,
        errorCode: error.code || "unknown"
      });
    } else {
      response.end(); // forcefully end corrupt response
    }
  }
});

注意:即使进行了所有这些更改,您仍然缺少任何形式的身份验证。考虑将 HTTPS 事件函数替换可调用函数,该函数为您处理但需要使用 Firebase 客户端 SDK。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么我的函数返回一个空数组?

如何根据匹配的ID返回一个对象数组?

显示一个数组但它返回空

猫鼬,快递返回一个空数组

$('div'); 返回一个空数组

返回一个空数组

改造返回一个空数组

Firestore 返回一个空数组

useEffect 返回一个空数组

我的搜索返回一个空数组

一个 java.lang.NullPointerException,我不知道出了什么问题

数组搜索返回一个新的空数组

我想从json列表中返回ID,但是它给出了一个错误

Javascript映射问题返回一个空值数组

Absinthe 返回一个包含一个空值而不是空数组的数组

分解,请帮助我看看d出了什么问题,我是一个刚学的新手

为什么slice返回一个空数组?

为什么这个函数返回一个空数组?

我想返回帖子数组,但我得到了一个空数组

我想获得一个ID的所有父ID上的数组

我在一个函数中有一个本地字符数组——当我返回数组名称时,为什么返回值是空的?

为什么我的reducer在react / redux中返回一个空数组?

为什么我的异步函数返回一个空数组

为什么我的 ipcMain 在读取数据库后返回一个空数组?

当条件不在id上时,findOrNew返回一个数组,而不是对象

如何定义具有多个 ID 但返回一个值的 Javascript 数组?

我的addbyAge()函数出了什么问题,导致一个人以某种方式失踪?

为什么我的方法返回一个null数组?

Lodash _.difference返回一个空数组