【问题标题】:How to write clean asynchronous requests that can be called again如何编写可以再次调用的干净异步请求
【发布时间】:2019-12-31 00:40:43
【问题描述】:

我正在尝试使用 Promises 和 Async await 清理我的代码。我的问题是我需要这些请求可以在之后通过相同的处理被召回。

我已经尝试过 Promises,但是如果我将所有内容都嵌套在函数中,它会很快变得一团糟。如何制作此代码,以便它仅在返回值时在 go() 异步函数中继续?

const request = require('request-promise');
require('console-stamp')(console, 'HH:MM:ss.l');
const colors = require('colors');
const kws = 'sweatsasaaser'.toLowerCase();
const size = 'Small';

go();

async function go(){
    const f = await getproduct()
    console.log('Finished ' + f)
    if (f == undefined) getproduct()
}

async function getproduct(){

    console.log('Requesting')
    let result = await request('https://www.supremenewyork.com/mobile_stock.json');
    let data = JSON.parse(result);
    let prodid;

    for (var i = 0; i < data.products_and_categories['Tops/Sweaters'].length; i++){

        if (data.products_and_categories['Tops/Sweaters'][i].name.toLowerCase().includes(kws)){
            console.info('Found product: '.green + data.products_and_categories['Tops/Sweaters'][i].name.green);
            return prodid = data.products_and_categories['Tops/Sweaters'][i].id;
        };
    };

    if (prodid == undefined){
        console.log(`Product id: ${prodid}`.blue);
        return prodid;
    }
    else {
        setTimeout(function(){
            //getproduct()
        }, 4000);
    }
}

【问题讨论】:

    标签: node.js asynchronous request request-promise


    【解决方案1】:

    写一个单独的函数:

    /** 
    * Re-executes an async function n times or until it resolves
    * @param {function} fn Function to call
    * @param {number} [times=3] Times to retry before rejecting
    * @param {number} [delay=1000] Delay between retries
    * @param {number} [i=0] Counter for how many times it's already retried
    */
    async function retry(fn, times = 3, delay = 1000, i = 0) {
      try {
        return await fn()
      } catch (error) {
        if (i < times) {
          await new Promise(r => setTimeout(r, delay))
          return retry(fn, times, delay, i + 1)
        }
        else throw error;
      }
    }
    

    让你的 main 函数 getproduct 简单地抛出错误

    else {
        // setTimeout(function(){
        //     //getproduct()
        // }, 4000)
        throw new Error('Cannot get productid')
    }
    

    并将其与新的retry 函数一起使用:

    async function go(){
      const f = await retry(getproduct, 3)
    

    如果您想传递参数,只需将其包装起来

    const f = await retry(() => getproduct(...args), 3)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-13
      • 2021-07-17
      • 2020-01-16
      相关资源
      最近更新 更多