idlize icon indicating copy to clipboard operation
idlize copied to clipboard

Suggestion: Include a IdleTask for simplifying some use cases of IdleQueue

Open Jamesernator opened this issue 7 years ago • 0 comments

Given generator's (two-way) coroutine design was designed in order to enable custom runners it would be good to have some runner built on top of IdleValue that can simplify writing.

Simple example:

const size = width * height * 4
const imageData = new Uint8Array(size)

// Just a simple whitenoise image generator
return new IdleTask(function*() {
  for (let i = 0 ; i < size ; i++) {
    // Allow scheduler to break this up as much as it needs
    yield
    imageData[i] = Math.floor(Math.random() * 256)
  }
  return imageData
})

Example implementation of IdleTask (doesn't handle things like const value = yield anotherIdleValue or other stuff like that though):

class IdleTask {
  constructor(genFunction) {
    this._job = genFunction()
    this._value = null
    this._ready = false

    const runUntilComplete = (idleDeadline) => {
      while (idleDeadline.timeRemaining() > 0) {
        const iterResult = this._job.next()
        if (iterResult.done) {
          this._ready = true
          this._value = iterResult.value
          return
        }
      }
      this._idleCallback = requestIdleCallback(runUntilComplete)
    }

    this._idleCallback = requestIdleCallback(runUntilComplete)
  }

  _runToCompletion() {
    while (true) {
      const iterResult = this._job.next()
      if (iterResult.done) {
        this._ready = true
        this._value = iterResult.value
        return this._value
      }
    }
  }

  getValue() {
    if (this._ready) {
      return this._value
    } else {
      cancelIdleCallback(this._idleCallback)
      return this._runToCompletion()
    }
  }
}

Jamesernator avatar Sep 21 '18 01:09 Jamesernator