idnexeeddb draft, microqueue fixes

This commit is contained in:
Ilya Kantor 2019-03-11 14:14:41 +03:00
parent 364e707b2a
commit 32bf3fdb08
5 changed files with 627 additions and 18 deletions

View file

@ -281,11 +281,31 @@ In case of an error, it propagates as usual: from the failed promise to `Promise
````
## Timiing: async/await and higher-level actions
## Microtask queue: await and higher-level actions [#microtask-queue]
Some async stuff is more asynchronous than the other.
TODO
For instance, `setTimeout(handler, 0)` is async, and `let x = await f()` is async. What triggers first?
In the browser, or other environments we have two types of async actions:
1. `async/await`
2. `setTimeout` calls that are to execute, pending events
`Async/await` is based on promises, so it uses the promise queue internally, so-called "microtask queue".
When a promise is ready, it's handling is put to a special internal queue, and processed when Javascript has finished with the current code.
That's explained in detail in the chapter <info:promise-queue>. Promise `.then/catch/finally` handlers get queued, and then executed when the currently running code is complete.
If we use `async/await`, things are much simpler than with promises. No chaining. So we don't care much about that internal queue.
But there's an important side effect that we should understand: some async stuff is more asynchronous than the other.
For instance, we have:
- `setTimeout(handler, 0)`, that should run `handler` with zero delay.
- `let x = await f()`, function `f()` is async, but returns immediateley.
Which one runs first if `await` is *below* `setTimeout` in the code?
```js run
async function f() {
@ -293,19 +313,22 @@ async function f() {
}
(async () => {
setTimeout(() => alert('timeout'), 0);
setTimeout(() => alert('timeout finished'), 0);
await f();
alert('await');
alert('await finished');
})();
```
There's no ambiguity here: `await` always finishes first.
Remember promise queue from the chapter <info:promise-queue>? Promise `.then/catch/finally` handlers get queued, and then executed when the currently running code is complete. By specification, the promise queue has higher priority than environment-specific handlers.
`Async/await` is based on promises, so it uses the same promise queue internally.
Internally, there`setTimeout` and event handlers are also processed in a queue
By specification, the promise queue has higher priority than environment-specific handlers.
So `await` is guaranteed to work before any `setTimeout` or other event handlers. That's actually quite essential, as we know that our async/await code flow will never be interrupted by other handlers or events.