Promises

without spread

The Promise object is used for asynchronous computations. A Promise represents a value which may be available now, or in the future, or never.

Quick Recap

// promise signature is function(resolve, reject)
new Promise((resolve, reject) => { /* do stuff */ })

// To create a new Promise we only need resolve and can immediately resolve it
new Promise(resolve => resolve())


// promises 'return' more promises, creating a chain of promises!

const promise1 = new Promise(resolve => resolve('I am resolved'))
promise1 instanceof Promise
// true

const promise2 = promise1.then(value => value)
promise2 instanceof Promise
// true

const promise3 = promise2.then(value => value)
promise3 instanceof Promise
// true

// each then-able returns another promise!

Promises return promises

// promise wrapper for setTimeout
const delayedValue = (delay, value) => new Promise(resolve => {
  setTimeout(() => resolve(value), delay)
})

// new promise
new Promise(resolve => resolve())
  .then(() => delayedValue(1000, 1))    // 'value' is undefined because we resolved with no arguments
  // 1 was returned inside of .then, so this is a promise

  .then(value => delayedValue(1000, value + 1))
  // value is a variable holding the fulfillment value
  // from the previous .then()

  .then(value => delayedValue(1000, value + 1))

  .then(console.log)
  // you get the idea...
  // in fact, we see this pattern a lot
// what if we want to return more than one value
// to be called as fulfilled in the next .then()

new Promise(resolve => resolve())
  .then(() => {
    /*
     * 1st problem: How do we return 2 values here?  return 1,2 ??
     */
  })

  .then(
    /*
     * 2nd problem: How we we access those two values?
     */
  )

// turns out we can trick JavaScript into thinking we have a single value.

// The object!

new Promise(resolve => resolve())
  .then(() => {
    return {
      first: 1,
      second: 2
    }
  })

  .then(obj => {        // obj is a single value
    const first = obj.first
    const second = obj.second
    // first is 1
    // second is 2
  })


// feels like boilerplate, right?
// It doesn't have to be an object, we can use an array instead.

new Promise(resolve => resolve())
  .then(() => {
    return [
      1,
      2
    ]
  })

  .then(ary => {       // ary is a single array object
    const first = ary[0]
    const second = ary[1]
  })


// still boilerplate
// Q.spread()
// bluebird.spread()

var Promise = require("bluebird")


new Promise(resolve => resolve())
  .then(() => {
    return [
      1,
      2
    ]
  })

  .spread((first, second) => {
    // first is 1
    // second is 2
  })


// this is what we want!

// We can easily see that the .spread function is
// expecting the function signature to contain two arguments
// but with ES6 and array destructuring, we dont need Q nor bluebird.

new Promise(resolve => resolve())
  .then(() => {
    return [
      1,
      2
    ]
  })

  .then(([ first, second ]) => {
    // first is 1
    // second is 2
  })
// same thing but uses ES6 object destructuring

new Promise(resolve => resolve())
  .then(() => {
    return {
      first: 1,
      second: 2
    }
  })

  .then(({ first, second }) => {
    // first is 1
    // second is 2
  })

Promises without Spread

By Kevin Wu

Promises without Spread

SBJS lightning talk 10/27/2016

  • 194