【问题标题】:Using await in for of loop在 for of 循环中使用 await
【发布时间】:2020-09-30 08:31:25
【问题描述】:

我有一个函数:

  1. 从 mongodb 请求数据
  2. 根据结果对 Ebay 进行 API 调用
  3. 将 Ebay API 响应插入另一个 mongodb

我有一个版本(甚至更hacky)工作(见gist),但并不是所有的调用都得到执行。

我尝试将函数转换为 async / await 但我收到了Error: socket hung up 错误。根据我调用 Ebay API 的经验,这不是由于我向 API 端点发出的请求(即我正在获取的 URL),而是函数的其余部分出现了一些错误。

我想知道这是否与我在 for / of 循环中的 await 有关。

谁能建议用 async / await 构造这个函数的正确方法?

exports = async function(payload) {
const axios = require("axios");
const throttledQueue = require('throttled-queue'); // not used in this example, but I need to throttle the requests once I figure out the rest of the function
let throttle = throttledQueue(5, 1000, true);

let ebayCollection = context.services.get("mongodb-atlas").db("cards").collection("ebay-prices");
let cardCollection = context.services.get("mongodb-atlas").db("cards").collection("stuart collection");


//Get wanted cards from card collection
let ownedCards = await cardCollection.find({
    forTrade: "Yes"
}).toArray(); //change back to status:Want after testing.


async function insertCards(ownedCards) {
    try {
        for (let card of ownedCards) {
            let url = "http://svcs.ebay.com/services/search/FindingService/v1?GLOBAL-ID=EBAY-US&REST-PAYLOAD&keywords=" + card.brand + " " + card.series + " " + card.player +
                "&itemFilter(0).name=SoldItemsOnly&itemFilter(0).value=true&OPERATION-NAME=findCompletedItems&paginationInput.entriesPerPage=6&paginationInput.pageNumber=1&RESPONSE-DATA-FORMAT=json&SECURITY-APPNAME=<myapp>&SERVICE-NAME=FindingService&SERVICE-VERSION=1.12.0";
            let cardId = card.card_id;
            console.log(url);
            const resp = await axios.get(url);
            console.log(resp);
            for (const item in resp.data.findCompletedItemsResponse[0].searchResult[0].item) {
                const itemId = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].itemId[0];
                const title = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].title[0];
                const galleryURL = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].galleryURL[0];
                const endDate = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].listingInfo[0].endTime[0];
                const price = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].sellingStatus[0].currentPrice[0].__value__;
                const currencyId = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].sellingStatus[0].currentPrice[0]['@currencyId'];

                const result = ebayCollection.updateOne({
                    itemId: itemId
                }, {
                    $addToSet: {
                        cardId: cardId
                    },
                    $set: {
                        itemId: itemId,
                        title: title,
                        endDate: endDate,
                        price: price,
                        currencyId: currencyId,
                        galleryURL: galleryURL
                    }
                }, {
                    upsert: true
                })

            }
        }

    } catch (error) {
        console.log("THIS IS THE ERROR" + error); // catches both errors
    }
}

await insertCards(ownedCards);
};

【问题讨论】:

  • 请发布完整的错误(哪一行)和调用堆栈(如果可能),以便于调试您的代码。
  • 您没有对查询字符串进行编码。尝试使用querystring 模块对其进行编码
  • @namgold 错误只是在我的 catch 块中输出。控制台显示 THIS IS THE ERRORError: socket hang up > result: { "$undefined": true } > result (JavaScript): EJSON.parse('{"$undefined":true}')
  • @Salil 感谢您的评论。我认为这不是问题 - 我在问题中链接到的 gist 版本以相同的方式使用查询字符串并且请求有效

标签: node.js mongodb async-await


【解决方案1】:

好的,在通过这个问题NodeJS - What does "socket hang up" actually mean?的所有cmets之后,我将我的请求更改为https并且问题已经停止。

我稍微调整了我的代码并合并了throttled-queue 以启用速率限制 - 它在下面,以防它对任何人有用。

exports = async function(payload) {
const axios = require("axios");
const throttledQueue = require('throttled-queue');
let throttle = throttledQueue(15, 10000, true);

let ebayCollection = context.services.get("mongodb-atlas").db("cards").collection("ebay-prices");
let cardCollection = context.services.get("mongodb-atlas").db("cards").collection("stuart collection");


//Get wanted cards from card collection
let ownedCards = await cardCollection.find({status: "Want"}).toArray(); //change back to status:Want after testing.


async function insertCards(ownedCards) {
    try {
      for (let card of ownedCards) {
        let url = "https://svcs.ebay.com/services/search/FindingService/v1?GLOBAL-ID=EBAY-US&REST-PAYLOAD&keywords=" + card.brand + " " + card.series + " " + card.player +
            "&itemFilter(0).name=SoldItemsOnly&itemFilter(0).value=true&OPERATION-NAME=findCompletedItems&paginationInput.entriesPerPage=6&paginationInput.pageNumber=1&RESPONSE-DATA-FORMAT=json&SECURITY-APPNAME=<myapp>&SERVICE-NAME=FindingService&SERVICE-VERSION=1.12.0";
            let cardId = card.card_id;
            console.log(url);
           const resp = await axios.get(url);
           console.log(resp);
           for (const item in resp.data.findCompletedItemsResponse[0].searchResult[0].item) {
            const itemId = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].itemId[0];
            const title = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].title[0];
            const galleryURL = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].galleryURL[0];
            const endDate = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].listingInfo[0].endTime[0];
            const price = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].sellingStatus[0].currentPrice[0].__value__;
            const currencyId = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].sellingStatus[0].currentPrice[0]['@currencyId'];

            const result = ebayCollection.updateOne({
                itemId: itemId
            }, {
                $addToSet: {
                    cardId: cardId
                },
                $set: {
                    itemId: itemId,
                    title: title,
                    endDate: endDate,
                    price: price,
                    currencyId: currencyId,
                    galleryURL: galleryURL
                }
            }, {
                upsert: true
            })

           }
      }

    } catch (error) {
      console.log("THIS IS THE ERROR"+ error); // catches both errors
    }
  }

  throttle(
    await function() {
        // make the request.
        insertCards(ownedCards);
    });
};

【讨论】:

    猜你喜欢
    • 2021-08-26
    • 2019-02-19
    • 1970-01-01
    • 2020-07-10
    • 2021-08-15
    • 2015-07-05
    • 2018-01-12
    • 1970-01-01
    • 2016-03-27
    相关资源
    最近更新 更多