JavaScript Async - Returning Promises
Written by Ian Elliot   
Monday, 15 November 2021
Article Index
JavaScript Async - Returning Promises
Currying

The second is to use a technique from functional programming called "currying" to reduce the number of parameters in the function.

For example:

getTime(); 
delay(1000)
  .then(getTime)
  .then(function(){return delay(1000,0);})
  .then(getTime);

In this case we have used the anonymous function to curry the delay function, i.e. we have reduced the number of parameters to zero. If you try this you will find that it works and each of the times is roughly 1000ms apart.

You can take this one-off currying and create a function that will automatically curry delay for you, for example:

function delay(t,p) { 
  return function () {
           var promise = new Promise(
function(resolve,reject){ setTimeout( function () { var r = Math.random(); if (r > p) { resolve(r); } else { reject(r); } }, t);
}
return p; }; }

You can see that this is the same idea, but now the delay function returns a function that delays for t milliseconds with no parameters. With this version of delay you can use:

getTime(); 
delay(1000)()
  .then(getTime)
   .then(delay(1000)) 
    .then(getTime);

The extra parentheses following the first use of delay are not a misprint. The delay function returns a function that delays for t milliseconds and to implement the delay it has to be called.

The need for the double pairs of parentheses is not nice, but there seems to be no way that a function that returns a Promise and accepts parameters can be used in the same way outside and inside a then.

The final way of doing the job is to use bind to curry the delay function. The bind function returns another function with a specified context and fixed values for any of its parameters. Using the original delay function we can call it in a then using:

 getTime();
 delay(1000)
  .then(getTime)
   .then( delay.bind(null,1000,0))
    .then(getTime);

The bind returns a function with the call context set to null and the first parameter set to 1000 and the second to 0. The call to bind is reputed to be slow.

Of the solutions, probably the best is to write the function using a parameter and remember to wrap it in an anonymous currying function if you use it in a then:

 .then(function(){return delay(1000);})

This is one of the negative features of using Promises.

You have to remember that a function that returns a Promise can have parameters, but you cannot specify these parameters when you use the function in a then unless you use currying or something similar.

Included In Chapter But Not In This Extract

  • Composing Promises
  • Web Worker With Promises
  • Thenables
  • Reporting Progress
  • The ProgressPromise Object
  • Beyond Promises

 

Summary

  • Promises are designed to restrict access to the resolve and reject functions to the code that creates the Promise.

  • This used to be done using a separate deferred object which was kept private.

  • The Promise standard makes use of the revealing constructor pattern to keep resolve and reject private, while allowing the code that creates the Promise to submit to the constructor a function that makes use of them.

  • The revealing constructor pattern extends the way a closure provides private variables and functions to the constructed object by passing private variables to a function that is passed to the constructor.

  • The functions that are called by the resolve and reject functions are set by the then method. As with callbacks you cannot pass parameters to these functions because this causes them to be evaluated.

  • 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.

  • You can arrange to return a Promise when you start a new worker thread and use this to obtain the final result of the thread.

  • One problem with using Promises with Worker threads is that they provide no way to handle an update message for progress reporting.

  • It is possible to modify the then function of a Promise so that it can be used to specify an onProgress handler.

  • It is also possible, but not straightforward, to derive a new Promise object from the standard one, which implements the then that makes use of an onProgress handler.

 

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 - Advanced Worker Threads 
  6. Consuming Promises 
  7. Producing Promises
      extract - The Revealing Constructor Pattern
     
    extract - Returning Promises ***NEW
     
    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.

square

 



 

Comments




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

<ASIN:1871962560>

<ASIN:1871962579>

 <ASIN:1871962528>

<ASIN:1871962501>

 



Last Updated ( Monday, 15 November 2021 )