Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaScript Promises - Thinking Sync in an Async World

Kerrick Long
February 06, 2014

JavaScript Promises - Thinking Sync in an Async World

Presented at the STL Ember.js Meetup on 2014-02-06. Video: http://youtu.be/wc72cyYt8-c

Kerrick Long

February 06, 2014
Tweet

More Decks by Kerrick Long

Other Decks in Programming

Transcript

  1. JavaScript
    Promises
    Thinking Sync in an Async World
    then

    View Slide

  2. Kerrick Long
    Things I make and do Where to find me online
    twitter.com/KerrickLong
    github.com/Kerrick
    Lead Front-end Developer!
    at Second Street
    KerrickLong.com
    www.
    meetup.com/STLEmber

    View Slide

  3. try {!
    console.log(getLatestGrade(getStudent(name)));!
    }!
    catch (error) {!
    logError(error);!
    }!
    finally {!
    logOut();!
    }!

    View Slide

  4. try {!
    console.log(getLatestGrade(getStudent(name)));!
    }!
    catch (error) {!
    logError(error);!
    }!
    finally {!
    logOut();!
    }!
    XMLHttpRequest

    View Slide

  5. getStudent(name, function(student) {!
    getLatestGrade(student, function(grade) {!
    console.log(grade);!
    logOut();!
    });!
    });!

    View Slide

  6. var handleError = function(error) {!
    logError(error);!
    logOut();!
    };!
    getStudent(name, function(error, student) {!
    if (error) return handleError(error);!
    getLatestGrade(student, function(error, grade) {!
    if (error) return handleError(error);!
    console.log(grade);!
    logOut();!
    });!
    });!

    View Slide

  7. var handleError = function(error) {!
    logError(error);!
    logOut();!
    };!
    getStudent(name, {!
    error: handleError,!
    success: function(student) {!
    getLatestGrade(student, {!
    error: handleError!
    success: function(grade) {!
    console.log(grade);!
    logOut();!
    },!
    })!
    },!
    });!

    View Slide

  8. try {!
    console.log(getLatestGrade(getStudent(name)));!
    }!
    catch (error) {!
    logError(error);!
    }!
    finally {!
    logOut();!
    }!
    Awesome

    View Slide

  9. var handleError = function(error) {!
    logError(error);!
    logOut();!
    };!
    getStudent(name, {!
    error: handleError,!
    success: function(student) {!
    getLatestGrade(student, {!
    error: handleError!
    success: function(grade) {!
    console.log(grade);!
    logOut();!
    },!
    })!
    },!
    });!
    Awkward.

    View Slide

  10. getStudent(name)!
    .then(getLatestGrade)!
    .then(console.log)!
    .catch(logError)!
    .then(logOut)!
    ;!
    Promises

    View Slide

  11. View Slide

  12. Promise Basics

    View Slide

  13. Promise Basics
    Consuming Promises

    View Slide

  14. Promise Basics
    Consuming Promises
    Creating Promises

    View Slide

  15. Promise Basics
    Consuming Promises
    Creating Promises
    Advanced Techniques

    View Slide

  16. Promise Basics

    View Slide

  17. Getting Promises

    View Slide

  18. View Slide

  19. RSVP.js
    Q.js • Bluebird

    View Slide

  20. RSVP.js
    Q.js • Bluebird
    Promises/A+

    View Slide

  21. Promise Guarantees

    View Slide

  22. Always Async

    View Slide

  23. Always Async
    Returns a Promise

    View Slide

  24. Always Async
    Returns a Promise
    Handled Once

    View Slide

  25. Always Async
    Returns a Promise
    Handled Once
    Then’able

    View Slide

  26. Promise States

    View Slide

  27. Promise States
    Pending Fulfilled Rejected

    View Slide

  28. Promise States
    Pending Fulfilled Rejected
    }
    Settled

    View Slide

  29. Promise States
    Pending Fulfilled Rejected

    View Slide

  30. Promise States
    Pending Fulfilled Rejected
    Value
    Reason

    View Slide

  31. Promise States
    Pending Fulfilled Rejected
    Return Value
    Thrown Exception

    View Slide

  32. Consuming Promises

    View Slide

  33. Promise Prototype
    Methods

    View Slide

  34. getJSON('/comments')!
    .then(onFulfilled, onRejected)
    Promise.prototype.then

    View Slide

  35. getJSON('/comments')!
    .then(function(comments) {!
    if (comments) return 'Good'!
    else throw new Error('Bad')!
    }, function(reason) {!
    // handle getJSON errors!
    })
    Promise.prototype.then

    View Slide

  36. getJSON('/comments')!
    .then(fulfillOne, rejectOne)!
    .then(fulfillTwo)!
    .then(null, rejectTwo)
    Promise.prototype.then

    View Slide

  37. getJSON('/comments')!
    .then(fulfillOne, rejectOne)!
    .then(fulfillTwo)!
    .then(null, rejectTwo)
    Promise.prototype.then
    THROW

    View Slide

  38. getJSON('/comments')!
    .then(fulfillOne, rejectOne)!
    .then(fulfillTwo)!
    .then(null, rejectTwo)
    Promise.prototype.then
    THROW

    View Slide

  39. getJSON
    onFulfilled onRejected
    getJSON
    onFulfilled
    onRejected

    View Slide

  40. getJSON('/comments') // waiting...!
    .then(extractFirstId)!
    .then(getCommentById) // waiting...!
    .then(showComment)
    Promise.prototype.then

    View Slide

  41. var promise = getJSON('/comments');!
    somethingElse();!
    promise.then(onFulfilled, onRejected);
    Promise.prototype.then

    View Slide

  42. getJSON('/comments')!
    .then(null, onRejected)
    Promise.prototype.catch

    View Slide

  43. getJSON('/comments')!
    .catch(onRejected)
    Promise.prototype.catch

    View Slide

  44. Promise Static
    Methods

    View Slide

  45. Promise.cast('Hi you!')!
    .then(onFulfilled, onRejected)
    Promise.cast

    View Slide

  46. Promise.cast(seededRandom(42))!
    .then(onFulfilled, onRejected)
    Promise.cast

    View Slide

  47. Promise.cast($.ajax(config))!
    .then(onFulfilled, onRejected)
    Promise.cast

    View Slide

  48. $.ajax(config)!
    .then(onFulfilled, onRejected)

    View Slide

  49. $.ajax(config)!
    .then(onFulfilled, onRejected)
    Lies, all LIES!

    View Slide

  50. Promise.cast($.ajax(config))!
    .then(onFulfilled, onRejected)
    Promise.cast

    View Slide

  51. var promises = [ getJSON('/a'),!
    getJSON('/b'), getJSON('/c') ]!
    !
    Promise.all(promises)!
    .then(allFulfilled, firstRejected)
    Promise.all

    View Slide

  52. var promises = [ getJSON('/a'),!
    'Hi you!', 42, getJSON('/c') ]!
    !
    Promise.all(promises)!
    .then(allFulfilled, firstRejected)
    Promise.all

    View Slide

  53. var promises = [ saveTo(server1),!
    saveTo(server2), saveTo(server3) ]!
    !
    Promise.race(promises)!
    .then(firstFulfilled, firstRejected)
    Promise.race

    View Slide

  54. Creating Promises

    View Slide

  55. new Promise()

    View Slide

  56. function() {!
    var name = prompt('Your name?')!
    if (!name)!
    throw new Error('Rude user!')!
    else!
    return name!
    }
    new Promise()

    View Slide

  57. new Promise(function(fulfill, reject) {!
    var name = prompt('Your name?')!
    if (!name)!
    throw new Error('Rude user!')!
    else!
    return name!
    })
    new Promise()

    View Slide

  58. new Promise(function(fulfill, reject) {!
    var name = prompt('Your name?')!
    if (!name)!
    reject(new Error('Rude user!'))!
    else!
    fulfill(name)!
    })
    new Promise()

    View Slide

  59. Shortcuts

    View Slide

  60. new Promise(function(fulfill, reject) {!
    fulfill(something)!
    })
    Promise.resolve()

    View Slide

  61. new Promise(function(fulfill, reject) {!
    fulfill(something)!
    })!
    Promise.resolve(something)
    Promise.resolve()

    View Slide

  62. new Promise(function(fulfill, reject) {!
    reject(something)!
    })
    Promise.reject()

    View Slide

  63. new Promise(function(fulfill, reject) {!
    reject(something)!
    })!
    Promise.reject(something)
    Promise.reject()

    View Slide

  64. Advanced Techniques

    View Slide

  65. this.get('name') // 'Kerrick'!
    !
    getJSON('/comments')!
    .then(function(comments) {!
    this.get('name') // throws!
    })
    this and bind()

    View Slide

  66. this.get('name') // 'Kerrick'!
    var self = this!
    getJSON('/comments')!
    .then(function(comments) {!
    self.get('name') // 'Kerrick'!
    })
    this and bind()

    View Slide

  67. this.get('name') // 'Kerrick'!
    !
    getJSON('/comments')!
    .then(function(comments) {!
    this.get('name') // 'Kerrick'!
    }.bind(this))
    this and bind()

    View Slide

  68. getJSON('/comments')!
    .then(function(comments) {!
    throw new Error('Hello?')!
    })
    Absorbed Rejections

    View Slide

  69. getJSON('/comments')!
    .then(function(comments) {!
    throw new Error('Hello?')!
    })!
    .catch(console.error.bind(console))
    Absorbed Rejections

    View Slide

  70. getStudent(name) // !
    .then(getLatestGrade)!
    .then(log)!
    .catch(logError)!
    .then(logOut)
    Promise-aware Functions

    View Slide

  71. log(getLatestGrade(getStudent(name)))!
    .catch(logError)!
    .then(logOut)
    Promise-aware Functions

    View Slide

  72. function getLatestGrade(promise) {!
    return Promise.cast(promise)!
    .then(function(value) {!
    // getLatestGrade Logic!
    })!
    }
    Promise-aware Functions

    View Slide