在达到承诺的API时添加延迟

时间:2017-03-10 03:40:42

标签: javascript node.js promise bluebird

以下是我获取商店列表及其产品

的代码

现在的问题是,返回商店产品清单的API有一个速率限制器,即10req / sec。因此,如果获得超过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)

3 个答案:

答案 0 :(得分:0)

理想情况下,您只需返回一个带有代码(在您的情况下为503)的响应,该代码显示“稍后再询问”并且具有直到下一次可用呼叫的时间(例如{ remainingTimeout: 3000 }),然后你会处理前端的等待。

答案 1 :(得分:0)

我创造了这个我过去成功使用的时髦功能

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))

答案 2 :(得分:0)

我的主要问题是服务只能满足10个请求/秒。为此我需要延迟我的电话。我得到的解决方案来自Promises的第三方库,即Bluebird

我用蓝鸟Promise.map

取代了Promise.all

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