Task is a thread abstraction. On lower level, new thread is created when needed, resources from thread pool can be reused. Creating threads to work one after another often times leads to this reusing.
Here we fill two tables, where we assign two accounts to John and one account to Joe. If we can ensure that John gets id=1 and Joe id=2, we can use parallelism and run these tasks as two independent threads (they don't race for resources).
In both threads we need to FIRST delete all the data from the table and THEN add our data. Instead of async/await pattern we used .then Promise chaining. This method returns calls its argument after the Promise on which it was called is fulfilled and returns another Promise which replaces the original one. In the syntax below we are guaranteed that John is inserted first and Joe second. Every SQLite table has default implicit rowid attribute, that works as integer autoincrement primary key.
In case of accounts table, we don't care in which order they run, so we can use a single .then. The fillDB function is not async and returns another promise that is fulfilled when both tables are filled. Then we use .then on its call in the onclick event, where we can also .catch rejected Promise (instead of try/catch syntax used in async/await pattern). The .catch bubbles up just like in Exception handling, so we can call it only on the topmost Promise if the error handling is the same.
The syntax can come in one of three forms
In all cases last inserted rowid is returned as the argument for the resolver, so we can obtain it like
Case (2) is similar to (1) except instead of object we provide two arrays. Case (3) allows to insert multiple rows.