When considering how to refactor the code within the ...
from the original snippet, the most suitable approach depends on the specific implementation of that code.
promiseRetry(function (retry, number) {
return doSomething()
.catch(retry);
})
.then(function (value) {
// ...using `value` here...
}, function (err) {
// ...using `err` here...
});
If we analyze this code which utilizes a two-argument version of then
, translating it into the equivalent using async
/await
presents some challenges:
let failed false;
let value;
try {
value = await promiseRetry((retry, number) => doSomething().catch(retry));
} catch (err) {
failed = true;
// ...using `err` here...
}
if (!failed) {
// ...using `value` here...
}
However, with additional context and information, there may be an opportunity to streamline the refactored code further.
Common practice typically involves simplifying the code as follows:
try {
const value = await promiseRetry((retry, number) => doSomething().catch(retry));
// ...using `value` here...
} catch (err) {
// ...using `err` here...
}
A notable distinction is in regards to error handling during the usage of ...using `value` here...
. The original code does not handle errors in this scenario, whereas in the revised approach shown above, all errors are caught uniformly.
promiseRetry(function (retry, number) {
return doSomething()
.catch(retry);
})
.then(function (value) {
// ...using `value` here...
})
.catch(function (err) {
// ...using `err` here...
});
This decision relates to whether rejections in the fulfillment handler should be handled separately from those in the rejection handler. In certain cases, such as retry scenarios, isolating these concerns can prevent unnecessary retries after a successful operation but a subsequent failure in processing the result. This rationale likely influenced the choice of the two-argument then
over then
/catch
in the original implementation.