【问题标题】:Using Promise and async together一起使用 Promise 和 async
【发布时间】:2020-03-15 11:25:25
【问题描述】:

我是 Node.js 的新手,我正在尝试理解使用错误处理并等待正确获得响应的想法。

所以我从网页请求一些数据,然后如果我完成了数据,但如果没有,那么它应该再次重试并获得直到达到最大数量。

这是我的代码:

const getData = (url) => {
    return new Promise((resolve, reject) => {
        const options = {
            method: 'GET',
            url: 'my url',
            headers: {
                Accept: 'application/json'
            }
        }
        function callBack(error, response) {
            if (!error) {
                let data = response.data;
                return resolve({ success: true, data: data, statusCode: response.statusCode })
            } else {
                return reject({ success: false, error: error })
            }
        }
        request(options, callBack)
    })
}

let count = 1
const retry = async (max, next) => {
    let result = await getData(url)
    if (result.code !== 200) {
        while (count < max) {
            console.log('failed, retrying... ' + count);
            count = count + 1
            retry(max, next);
        }
        return next('max retries reached', null)
    }
    console.log('success');
    next(null, result.data)
}

因此,在这部分之后,我尝试运行重试,直到获得 5 次数据,例如:

retry(5, 3000, function (err, data) {
   if (!err) {
      return data
   }
   return err                                
})

但是像这样运行重试功能意味着我不会等到我得到数据。如何在调用重试函数时使用 try/catch 或 .then 的思想,让它等待我的数据到来?

【问题讨论】:

  • retry() 中,您同时拥有迭代(while 循环)和递归(重试调用自身)。任何一个(写得正确)都可以完成这项工作,但不能两者兼而有之。

标签: node.js asynchronous promise async-await


【解决方案1】:

retry() 中,您需要迭代(使用 while 循环)递归(使用 retry() 调用自身),但不能同时进行。

如果你选择递归,那么一定要return retry()

传递next 函数不是必需的,因为retry() 将返回一个承诺。因此,在 retry 的调用者中,您可以链接 retry().then(...) 或 async/await 等效项。

应该这样做:

const retry = async(max, count) => {
    count = count || 0;
    let result;
    if(count >= max) { // top test; ensures that getData() isn't run even if say `retry(5, 10)` was accidentally (or deliberately) called.
        throw new Error('max reached'); // will not be caught below and will terminate the trying.
    }
    try {
        result = await getData(url);
        if(result.code !== 200) {
            throw new Error(`getData() was unsuccessful (${result.code})`); // will be caught and acted on below
        }
        return result.data; // will bubble upwards through the call stack to retry's original caller
    }
    catch(error) {
        // all errors ending up here qualify for a retry
        console.log(error.message, `retrying... (${count})`);
        return retry(max, count + 1); // recurse
    }
}

// call as follows
retry(5).then(function(data) {
    // work with `data`
}).catch(function(error) {
    console.log(error);
    // take remedial action, rethrow `error`, or do nothing
});

在实践中,您可能会选择在重试之间引入延迟,以便为数据源提供更多时间来更改状态。

【讨论】:

    猜你喜欢
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 2019-07-27
    • 2013-01-15
    • 2017-10-26
    相关资源
    最近更新 更多