fix: [#2359] work around image decode limits in chromium (#2361)
Closes #2359
This PR switches away from `Image.decode()` to use the older method of `Image.onload` this method is more reliable for large or numerous images due to a chromium bug around decode.
@HxShard provided a great codesandbox illustrating the issue https://codesandbox.io/s/happy-gagarin-j1vjr
## Changes:
- Creates a new Future type for working with native Promises' resolve/reject at any time
- Creates a new Semaphore type that can limit async calls in between `enter` and `exit`
- Fixes a small clock schedule bug as well
authored by