Created
April 29, 2017 04:25
-
-
Save ymmn/e67e98c1c98e89b1f33242a2aa51c7dd to your computer and use it in GitHub Desktop.
implementing promises from scratch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Implementing promises from scratch. Turns out simple | |
* | |
* There are only two possibilities: | |
* 1. then() gets called before the async function finishes | |
* 2. then() gets called after the async function finishes | |
* | |
* as long as we handle both, we're good! | |
*/ | |
/** | |
* this approach was more intuitive at first | |
*/ | |
const promisify = (asyncFunc) => { | |
let _callback = null | |
let _retVal = null | |
let _resolved = false | |
asyncFunc((retVal) => { | |
_resolved = true | |
_retVal = retVal | |
if (_callback) { | |
_callback(retVal) | |
} | |
}) | |
return { | |
then: (callback) => { | |
_callback = callback | |
if (_resolved) { | |
callback(_retVal) | |
} | |
} | |
} | |
} | |
/** | |
* the class turns out to be cleaner | |
*/ | |
class MyPromise { | |
constructor(handler) { | |
this.resolved = false | |
this.result = null | |
this.thenHandler = null | |
handler(this.onResolve.bind(this)) | |
} | |
onResolve(...result) { | |
this.result = result | |
this.resolved = true | |
this.tryToResolve() | |
} | |
tryToResolve() { | |
if (this.resolved && this.thenHandler) { | |
this.thenHandler(...this.result) | |
} | |
} | |
then(handler) { | |
this.thenHandler = handler | |
this.tryToResolve() | |
} | |
} | |
/** | |
* test 'em out | |
*/ | |
const syncResolver = style => resolve => { | |
resolve(`sync resolved, ${style} style!`) | |
} | |
const asyncResolver = style => resolve => { | |
setTimeout(() => { | |
resolve(`async resolved, ${style} style!`) | |
}, 1000) | |
} | |
new MyPromise(syncResolver('class')).then(data => { | |
console.log(data) | |
}) | |
new MyPromise(asyncResolver('class')).then(data => { | |
console.log(data) | |
}) | |
promisify(syncResolver('func')).then(data => { | |
console.log(data) | |
}) | |
promisify(asyncResolver('func')).then(data => { | |
console.log(data) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment