JavaScript Async - Composing Promises
Written by Ian Elliot   
Monday, 13 July 2020
Article Index
JavaScript Async - Composing Promises
Any

Any

What would be better is an implementation of any, which is found in some Promise libraries and soon to be included in ECMAScript. Any returns the first successful result, or a reject if there is no successful function at all:

function any(args) {
var number = args.length; var p = new Promise( function (resolve, reject) { args.map( function (p) {
p.then( function (value) { resolve(value); }, function (error) { if (--number === 0) { reject(error); } }); });
}); return p; }

This works in a very similar way to race, but we now maintain a count of the number of Promises included in the arguments. Each time a Promise is rejected we reduce the count by one. If the count reaches zero then all of the Promises have been rejected and we change the state of the returned Promise to rejected. Notice that as long as one of the Promises resolves, the returned Promise resolves. As before, we make no attempt to cancel any no longer wanted Promises or tasks.

coverasync

Timeout

As a final example, and one that is useful in practice, let's explore a timeOut function. One of the problems with Promises is that they don't have a timeout. If a Promise isn't resolved or rejected then it will continue to be pending forever.

The following function takes a Promise and returns a new Promise that will reject if the original Promise doesn't accept or reject within the specified timeout:

function timeOut(p, t) {
   var promise = new Promise(
		  function (resolve, reject) {
			  p.then(function (value) {
		     	  resolve(value);
	  	  },
function (error) { reject(error); }); setTimeout(function () { reject("timeout"); }, t); }); return promise; }

Again, this is very simple. All that happens is that a new Promise is created and is resolved if the original Promise resolves, or rejected if the setTimeout is triggered first.

For example:

myPromise = delay(2000, 0);
timeOut(myPromise, 1000).then(
	function () {
		console.log("success");
	},
	function () {
		console.log("failure");
	});

In this case the Promise times out and fails. If you change the delay to less than 1000 milliseconds then the Promise succeeds. This would be easier to use as a method added to the Promise object because then it could be used with chaining.

Summary

  • The basic Promise object provides a few basic ways to combine Promises – all and race – but it isn’t difficult to create new functions which combine Promises in any way that you need. For example you can create a Promise with a timeout or a version of race that returns the first Promise to resolve, not just the first to settle.

 

Now Available as a Book:

 JavaScript Async

cover

You can buy it from: Amazon

Contents

  1. Modern JavaScript (Book Only)
  2. Events,Standard & Custom
  3. The Callback
      extract - The Callback & The Controller
  4. Custom Async - setTimeout, sendMessage & yield
      extract - Custom Async
      extract - Avoiding State With Yield 
  5. Worker Threads
      extract - Basic Worker ***NEW
      extract - Advanced Worker Threads 
  6. Consuming Promises 
  7. Producing Promises
      extract - The Revealing Constructor Pattern
     
    extract - Returning Promises
     
    extract - Composing Promises
  8. The Dispatch Queue
      extract - Microtasks
  9. Async & Await
      extract -  Basic Async & Await
      extract -  DoEvents & Microtasks
  10. Fetch, Cache & Service Worker
      extract - Fetch  
      extract - Cache
     
    extract -  Service Workers

Also by Ian Elliot

Just JavaScript: An Idiomatic Approach
Just jQuery: The Core UI 
Just jQuery: Events, Async & AJAX

 

 

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

raspberry pi books

 

Comments




or email your comment to: comments@i-programmer.info

<ASIN:1871962560>

<ASIN:1871962579>

 <ASIN:1871962528>

<ASIN:1871962501>

 

 



Last Updated ( Saturday, 12 September 2020 )