diff --git a/lib/src/promise/base.ts b/lib/src/promise/base.ts index ec26e69..41e7538 100644 --- a/lib/src/promise/base.ts +++ b/lib/src/promise/base.ts @@ -205,13 +205,15 @@ export function _createPromise(newPromise: PromiseCreatorFn, processor: Promi let catchFinally: any = onFinally; if (isFunction(onFinally)) { thenFinally = function(value: TResult1 | TResult2) { - onFinally && onFinally(); - return value; + return doAwait(onFinally && onFinally(), () => { + return value; + }); } catchFinally = function(reason: any) { - onFinally && onFinally(); - throw reason; + return doAwait(onFinally && onFinally(), () => { + throw reason; + }); } } diff --git a/lib/test/src/promise/use.await.test.ts b/lib/test/src/promise/use.await.test.ts index 1fa6023..2327e84 100644 --- a/lib/test/src/promise/use.await.test.ts +++ b/lib/test/src/promise/use.await.test.ts @@ -1413,6 +1413,63 @@ function batchTests(testKey: string, definition: TestDefinition) { }).finally(()=> 77), 2, "Expect the result to be 2"); }); + it("check finally waits for returned promise on resolve", async () => { + let finallyCalled = false; + let promise = createNewPromise((resolve, reject) => { + resolve(2); + }).finally(() => { + return createNewPromise((resolve) => { + scheduleTimeout(() => { + finallyCalled = true; + resolve(); + }, 10); + }); + }); + + assert.equal(finallyCalled, false, "finally should not be called synchronously"); + let result = await promise; + assert.equal(result, 2, "Expect the result to be 2"); + assert.equal(finallyCalled, true, "finally promise should complete before resolve"); + }); + + it("check finally waits for returned promise on reject", async () => { + let finallyCalled = false; + let finallyRejectReason = new Error("finally-reject"); + try { + await createRejectedPromise(new Error("main-reject")).finally(() => { + return createNewPromise((resolve, reject) => { + scheduleTimeout(() => { + finallyCalled = true; + reject(finallyRejectReason); + }, 10); + }); + }); + assert.ok(false, "Expected the promise to reject"); + } catch (e) { + assert.equal(e, finallyRejectReason, "Expected the finally rejection reason"); + assert.equal(finallyCalled, true, "finally promise should complete before reject"); + } + }); + + it("check finally preserves original rejection when returned promise resolves", async () => { + let finallyCalled = false; + let mainRejectReason = new Error("main-reject"); + try { + await createRejectedPromise(mainRejectReason).finally(() => { + return createNewPromise((resolve) => { + scheduleTimeout(() => { + finallyCalled = true; + resolve(); + }, 10); + }); + }); + assert.ok(false, "Expected the promise to reject"); + } catch (e) { + assert.equal(e, mainRejectReason, "Expected the original rejection reason"); + assert.equal(finallyCalled, true, "finally promise should complete before reject"); + } + }); + it("check creating a resolved promise with another promise", async () => { let otherPromise = createNewPromise((resolve, reject) => {