Search code examples
javascripttypescriptcoding-stylees6-promise

How can I make these JS code more elegant?


I have encounter a coding problem. I try to insert some style elements to HTML, and when these style loaded, console log "done"

var genStyle = () => {
  const instance = {}
  setTimeout(() => {
    instance.onload && instance.onload()
  }, Math.random() * 3000)
  return instance
}

var a = genStyle()
var b = genStyle()
var c = genStyle()

/* implementation start */

Promise.all([

]).then(() => console.log('all done'))

/* implementation end */

I complete it like this, but I think its ugly. Could you give a more elegant one?

var genStyle = () => {
  const instance = {}
  setTimeout(() => {
    instance.onload && instance.onload()
  }, Math.random() * 3000)
  return instance
}

var a = genStyle()
var b = genStyle()
var c = genStyle()

/* implementation start */

const wrapper = x => {
  let tick = null
  const promise = new Promise(resolve => tick = resolve)
  x.onload = tick
  return promise
}

Promise.all([
  wrapper(a),
  wrapper(b),
  wrapper(c)
]).then(() => console.log('all done'))

/* implementation end */

Solution

  • There's no need for there to be an outer tick variable that gets reassigned to the resolve function - you can return the Promise directly.

    const wrapper = x => new Promise((resolve) => {
      x.onload = resolve;
    });
    

    Ideally you'd also have an array of instances instead of 3 separate standalone identifiers to begin with, if that's something you're permitted to do.

    const genStyle = () => {
      const instance = {}
      setTimeout(() => {
        instance.onload && instance.onload()
      }, Math.random() * 3000)
      return instance
    }
    
    const instances = [genStyle(), genStyle(), genStyle()];
    const wrapper = x => new Promise((resolve) => {
      x.onload = resolve;
    });
    
    Promise.all(
      instances.map(wrapper)
    )
      .then(() => console.log('all done'))