【问题标题】:Add delay while hitting the API's in promise在承诺中点击 API 时添加延迟
【发布时间】:2017-03-11 22:42:52
【问题描述】:

下面是我获取商店列表然后是产品的代码

现在的问题是,返回商店产品列表的 API 有一个速率限制器,即 10req/秒。因此,如果获得超过 10 家商店并且我点击产品,API 开始给我 503,并且在响应中我得到未定义的值以及实际值。有没有办法可以设置超时,即在我的情况下延迟getProductList 的调用?

下面是代码

const shops = response.data
      return Promise.all(
        shops.map((shop) => {
          const id = shop.shop_id
          const shopobj = {
            id,
            name: shop.shop_name,
          }
          return favAPI.checkFavourite(uid, id)
            .then((favData) => {
              shopobj.is_fave_shop = favData

              // Fetch the products of shop
              return getProductList(id, uid)
                .then((responsedata) => {
                  shopobj.products = responsedata.data.products.map(product => ({
                    id:          product.id,
                    name:        product.name,
                  }))
                  return shopobj
                })
                .catch(() => { })
            })
            .catch(err => console.error(err))
        }))
        .then(responses => responses)
        .catch(err => console.log(err))

我可以这样做

return setTimeout(() => getProductList(id, uid)
                .then((responsedata) => {
                  shopobj.products = responsedata.data.products.map(product => ({
                    id: product.id,
                    name: product.name,
                    price: product.price,
                    image_url: product.image_url,
                    is_wishlist: userWishListProd.indexOf(product.id) > -1,
                    url: product.url,
                    shop_name: product.shop.name,
                    labels: product.labels,
                    badges: product.badges,
                  }))
                  return shopobj
                })
                .catch((err) => { console.error(err.name, err.statusCode, err.message) }), 30)

【问题讨论】:

    标签: javascript node.js promise bluebird


    【解决方案1】:

    理想情况下,您只需返回一个带有代码(在您的情况下为 503)的响应,上面写着“稍后再问”,并且在正文中具有直到下一次可用调用的时间量(例如:{ remainingTimeout: 3000 }),然后您将处理前端的等待。

    【讨论】:

    • 我同意,但避免达到速率限制会更“礼貌”:p
    【解决方案2】:

    我创建了这个看起来很时髦的函数,我过去曾成功使用过该函数

    const rateLimited = perSecond => {
        perSecond = (isNaN(perSecond) || perSecond < 0.0001) ? 0.0001 : perSecond;
        const milliSeconds = Math.floor(1000 / perSecond);
        let promise = Promise.resolve(performance.now());
        const add = cb => promise.then(lastRun => {
            const now = performance.now();
            const diff = now - lastRun;
            if (diff < milliSeconds) {
                promise = promise.thenWait(milliSeconds - diff).then(() => performance.now());
            }
            return promise.then(cb);
        });
        return add;
    };
    

    在您的代码中使用 .... 查找 // ******** 以查找对您的代码进行添加和更改的两个地方

    // ********
    // "create" the rate limited queue
    const limitedProductList = rateLimited(10); // 10 per second limit
    
    const shops = response.data;
    
    return Promise.all(
        shops.map((shop) => {
            const id = shop.shop_id
            const shopobj = {
                id,
                name: shop.shop_name,
            }
            return favAPI.checkFavourite(uid, id)
            .then((favData) => {
                shopobj.is_fave_shop = favData
                // ********
                // Fetch the products of shop using the rate limited queue
                return limitedProductList(() => getProductList(id, uid))
                .then((responsedata) => {
                    shopobj.products = responsedata.data.products.map(product => ({
                        id: product.id,
                        name: product.name,
                    }))
                    return shopobj
                })
                .catch(() => {})
            })
            .catch(err => console.error(err))
        })
    )
    .then(responses => responses)
    .catch(err => console.log(err))
    

    【讨论】:

      【解决方案3】:

      在我的案例中,主要问题是仅满足 10 个请求/秒的服务。为此,我需要延迟我的电话。我得到的解决方案来自 Promises 的 3rd 方库,即Bluebird

      我将 Promise.all 替换为 bluebird 的 Promise.map

      这有一个并发参数,您可以在其中指定限制。

      【讨论】:

        猜你喜欢
        • 2017-05-08
        • 1970-01-01
        • 2015-03-08
        • 2016-12-21
        • 2015-03-27
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多