JavaScript asynchrony: promises

node v6.17.1
version: 0.1.0
endpointsharetweet
Sources include Kyle Simpson, You Don't Know JS: Async & Performance
Here "promises" means the features provided by the ES2015 native Promise object — a "thenable" object, meaning an object possessing a 'then()' method. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise.
Promises solve problems related to asynchronous processing, but there are no (there can be no) guarantees regarding relative order of execution of *separate* promises (whether chained or not), as the logged output at the bottom of the page will demonstrate. The 'all()' method of the Promise object does allow for coordinating multiple separate promises (rather than chaining them), but it still provides no guarantees regarding relative order of execution.
Simple demonstration of the logic of the Promise() constructor used with the 'resolve()' method and the 'then()' method. In code order, we (1) Instantiate a promise with a function that will be executed once it is invoked by the instance's 'then()' method; (2) Invoke that function via the instance's 'then()' method. The function passed to the 'then()' method is executed once the function in the promise object instance has returned. Here the 'resolve()' method is not used to pass a message, but serves as a flow control signal.
p = () => new Promise(resolve => setTimeout(resolve, 1000)); p().then(() => console.log('Example 1: promise fulfilled'));
Example of using this pattern to return a message, by passing a function to the 'resolve()' method and then using the 'then()' method's first parameter to return the message data.
let foo = () => 'foo'; // data to be returned let getFoo = () => new Promise(resolve => setTimeout(resolve(foo(), 1000))); getFoo().then(onFulfilled => console.log('Example 2: ' + onFulfilled));
Using the 'reject()' method as well as the 'resolve()' method in the callback.
const rq = require('request-json-light'); let client = rq.newClient('http://jsonplaceholder.typicode.com/'); let clientGet = (client, slug, prop) => new Promise((resolve, reject) => client.get(slug, (error, response, body) => (response.statusCode === 200) ? resolve(body[prop]) : reject(response.statusCode)));
Using with both 'then()' and 'catch()' methods. Whatever is passed to the 'reject()' method will be caught.
clientGet(client, 'users/1', 'username') .then(username => console.log('Example 3: ' + username)) .catch(err => console.log(err));
Demonstration of error (should return a 404):
clientGet(client, 'foo', 'bar') .then(result => console.log(result)) .catch(err => console.log('Example 4: ' + err));
Here we chain 'then()' calls. The first value returned is modified.
clientGet(client, 'users/1', 'username') .then(username => username + 'foo') // 'Bret' -> 'Bretfoo' .then(usernamefoo => console.log('Example 5: ' + usernamefoo)) .catch(err => console.log(err));
Anothing chaining example. Here we pass another promise to the first 'then()' call. When the second promise is resolved, existing data is replaced by new data.
clientGet(client, 'users/1', 'username') .then(() => clientGet(client, 'users/2', 'username')) .then(username2 => console.log('Example 6: ' + username2)) .catch(err => console.log(err));
Use 'Promise.all()' to coordinate multiple promises:
let p1 = clientGet(client, 'users/1', 'username'), p2 = clientGet(client, 'users/2', 'username'); Promise.all([p1, p2]) .then(usernames => console.log('Example 7: ' + usernames)) // array [p1, p2] .catch(err => console.log(err));
Use 'Promise.race()' to obtain only the "winning" promise:
Promise.race([p1, p2]) .then(username => console.log('Example 8: winner is ' + username)) .catch(err => console.log(err));
Loading…

no comments

    sign in to comment