Reputation: 1863
I have a promise chain and I need to write to a file using fs.writeFile
after the chain is executed. As far as I can see, finally
accepts a Promise as a return type:
finally(onfinally?: (() => void) | undefined | null): Promise<T>
But looking at my code, eslint
doesn't seem to like it:
return this.downloadProject(data)
.finally(() => {
return fse.writeFile('', 'foo');
})
Is this caused by a misconfiguration of my Eslint or is this a code smell?
Upvotes: 1
Views: 1888
Reputation: 16253
Another alternative solution
function wait1sec() {
return new Promise((resolve, reject) => {
setTimeout(()=>resolve(1), 1000)
});
}
wait1sec()
.then((res) => {
console.log(res);
return wait1sec()
})
.catch((err) => {
console.error(err);
})
.finally(() => {
console.log(2)
return wait1sec()
})
.finally(() => {
console.log(3);
return wait1sec()
})
.finally(() => {
console.log(4);
})
.finally(() => {
console.log(5);
})
Upvotes: 0
Reputation: 350290
The ECMAScript specification has for finally
, in step 6:
i. Let result be ? Call(onFinally, undefined).
ii. Let promise be ? PromiseResolve(C, result).
...etc
So there is a use for the value returned. If this return value happens to be a promise, then the promise returned by finally
will be locked into the promise returned by its callback. However, the resolution value will still be that of the original promise.
This can be seen in the following test script:
Promise.resolve(3)
.finally(() => new Promise(resolve =>
setTimeout(() => resolve(5), 2000))
)
.then((value) => console.log("resolved to", value));
// Message appears after 2 seconds, and value is 3
And similarly, when the original promise is rejected, the promise returned in the finally
callback is awaited, but the rejection remains:
Promise.reject(3)
.finally(() => new Promise(resolve =>
setTimeout(() => resolve(5), 2000))
)
.catch((value) => console.log("rejected with", value));
// Message appears after 2 seconds, and value is 3
There is a clearly a consequence to returning a promise in the finally
callback, so we could argue that the linter should not complain about it.
If you want to work around this linter warning, or if you really want to have the effect of a then
, so that it returns a new promise with its own outcome, than weave a .catch
just before a .then
:
return this.downloadProject(data)
.catch(() => {}) // This promise will fulfill after a rejection
.then(() => {
return fse.writeFile('', 'foo');
})
Upvotes: 4
Reputation: 1327
The .finally
returns a promise, in order to allow promise-chaining. However, the function inside should not return anything, hence the () => void | undefined
.
Upvotes: 2