Skip to content

Conversation

@Perryvw
Copy link
Member

@Perryvw Perryvw commented Jul 20, 2021

Out of scope: async/await, will be done in follow-up PR

Implemented promises based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise and a little bit of https://promisesaplus.com/

Note: For now we are deviating from the spec in an important aspect: currently the promise constructor function is executed immediately, instead of waiting until there is no more user code on stack, like the promise spec mandates.

@Perryvw Perryvw requested review from lolleko and tomblind July 20, 2021 20:07
@Perryvw Perryvw self-assigned this Jul 20, 2021
@Perryvw Perryvw marked this pull request as draft July 20, 2021 20:34
@Perryvw
Copy link
Member Author

Perryvw commented Jul 20, 2021

Woops, putting this back into draft after realising I forgot the case where then() is called on an already-resolved promise.

@Perryvw Perryvw marked this pull request as ready for review July 22, 2021 18:56
@Perryvw
Copy link
Member Author

Perryvw commented Jul 22, 2021

Woops, putting this back into draft after realising I forgot the case where then() is called on an already-resolved promise.

Problem solved.

# Conflicts:
#	src/LuaLib.ts
#	src/lualib/declarations/global.d.ts
Copy link
Collaborator

@tomblind tomblind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I don't see represented in the tests is direct chaining:
promise.then(...).then(...).catch(...)
It might be good to test this to ensure these calls are returning the correct thing.


util.testFunction`
// Wrap function getUserData(id: number, callback: (userData: UserData) => void) into a Promise
async function getUserDataAsync(id: number): Promise<UserData> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dumb question: how does this work if we don't support async yet?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works because async keyword has no special function yet and will just be ignored. You are right that this is a a strange async, and in fact I think it is removed again in my async/await branch. I will remove it here too.

`
.setTsHeader(promiseTestLib)
.expectToEqual(["finally"]);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe another test for finally that checks that this:

myPromise
.then(response => {
  doSomething(response);
  runFinalCode();
})
.catch(e => {
  returnError(e);
  runFinalCode();
});

is equivalent to this:

myPromise
.then(response => {
  doSomething(response);
})
.catch(e => {
  returnError(e);
})
.finally(() => {
  runFinalCode();
});

(Source: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Promises#running_some_final_code_after_a_promise_fulfillsrejects)

Can possibly be implemented like this:

const { noThrow, noThrowResolve } = defer<string>();
const { throw_, throwResolve } = defer<string>();

noThrow.then(
     data => { log(data); log("finally"); }
)
.catch(
    e => { log(e); log("finally"); }
);

throw_.then(
     data => { throw data; log("finally"); }
)
.catch(
    e => { log(e); log("finally"); }
);

noThrowResolve("test");
throwResolve("test");

const { finallyNoThrow, finallyNoThrowResolve } = defer<string>();
const { finallyThrow, finallyThrowResolve } = defer<string>();

finallyNoThrow.then(
     data => { log(data); }
)
.catch(
    e => { log(e); }
)
.finally(
    () => { log("finally"); }
);

finallyThrow.then(
     data => { throw data; }
)
.catch(
    e => { log(e); }
)
.finally(
    () => { log("finally"); }
);


finallyNoThrow("test");
finallyThrow("test");

return allLogs;

// expectToEqual(["test", "finally", "test", "finally", "test", "finally", "test", "finally"])

@Perryvw Perryvw merged commit f6fea1e into master Aug 18, 2021
@Perryvw Perryvw deleted the promises branch August 18, 2021 08:06
sanikoyes pushed a commit to sanikoyes/TypeScriptToLua that referenced this pull request Sep 24, 2021
* Initial lualib promise class implementation

* First promise tests

* More promise tests

* Promise class implementation

* Implemented Promise.all

* Promise.any

* Promise.race

* Promise.allSettled

* fix prettier

* Add promise example usage test

* Added missing lualib dependencies for PromiseConstructor functions

* Immediately call then/catch/finally callbacks on promises that are already resolved

* Transform all references to Promise to __TS__Promise

* PR feedback

* Removed incorrect asyncs

* Add test for direct chaining

* Add test for finally and correct wrong behavior it caught

* Added test throwing in parallel and chained then onFulfilleds

* Fixed pull request link in ArrayIsArray lualib comment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants