Javascript Async

satya - 5/11/2019, 8:17:02 PM

Lets understand what this code is doing


const ftp = require("basic-ftp")
const client = new ftp.Client()

let AWS = require('aws-sdk');
let sns = new AWS.SNS();

module.exports.publish = async (event) => {
    const listening = await client.access({
            host: 'ip-address',
            user: 'user',
            password: 'password'
    }).then(async()=>{
         return client.list()
    });
    
    const p_array = listening.map((directory)=>{
        const path = '/'+(directory.name) ;
        return wrap(path)
    })
    
    return Promise.all(p_array).then(async()=>{
        await client.close();
    })

};

function wrap(directory){
    const params = {
      Message: directory,
      TopicArn: 'arn:aws:sns:us-east-2:760202155994:topic-name'
    };
    
    const p = sns.publish(params).promise();
    
    return p.catch((err) => {
        console.error(err, err.stack);
    });
    
}

satya - 5/11/2019, 8:17:39 PM

Import the modules



//ftp
const ftp = require("basic-ftp")
const client = new ftp.Client()

//aws services
let AWS = require('aws-sdk');
let sns = new AWS.SNS();

satya - 5/11/2019, 8:18:49 PM

Jacascript async function definition

Jacascript async function definition

Search for: Jacascript async function definition

satya - 5/11/2019, 8:31:12 PM

understand javascript promises

understand javascript promises

Search for: understand javascript promises

satya - 5/11/2019, 9:06:05 PM

what is an arrow function in javascript?

what is an arrow function in javascript?

Search for: what is an arrow function in javascript?

satya - 5/11/2019, 9:18:15 PM

whose passes resolve and reject in a promise?

whose passes resolve and reject in a promise?

Search for: whose passes resolve and reject in a promise?

satya - 5/11/2019, 9:18:24 PM

That is explained here

That is explained here

satya - 5/11/2019, 9:22:24 PM

The Promise as an object is acting as a collector of the output of the executor function


PromiseObj -> Run Executor code (inline typically)
  internal-resolve-method
  internal-reject-method

//Pass these two methods as inputs to the
//executor

//Loopy but that now makes sense

//the executor is a function definition
//not function invocation!!!
//So it only names its params!!

//So the receiver of the executor function
//has the responsibility to pass
//the needed callbacks!!

satya - 5/11/2019, 11:45:54 PM

For me easier to understand as cooperating objects

satya - 5/12/2019, 2:07:45 PM

Official doc on promis

Official doc on promis

satya - 5/12/2019, 2:10:09 PM

There is more to it: then

Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler, or to its original settled value if the promise was not handled (i.e. if the relevant handler onFulfilled or onRejected is not a function).

satya - 5/12/2019, 2:12:08 PM

So


Promise p = foo();

//p is a multivalued return
//with status pending
//it is an active value


function doThisOnGood(value){}
function doThisIfFails(){}

p.then(doThisOnGood, doThisIfFails);

satya - 5/12/2019, 2:15:02 PM

The then function of Promises in Javascript

The then function of Promises in Javascript

Search for: The then function of Promises in Javascript

satya - 5/12/2019, 2:18:25 PM

Chaining and then explained in this SOF question

Chaining and then explained in this SOF question

satya - 5/12/2019, 2:30:27 PM

when are the then handlers called?

Once a Promise is fulfilled or rejected, the respective handler function (onFulfilled or onRejected) will be called asynchronously (scheduled in the current thread loop).

satya - 5/12/2019, 2:30:47 PM

The then is explained better here (hopefully)

The then is explained better here (hopefully)

satya - 5/18/2019, 2:08:56 PM

Chained Promises

satya - 5/18/2019, 2:13:55 PM

Few more points

P1 is typically returned by a function. Likely that function when completes calls P1's functions to inform done or not done.

Before the P1 is fulfilled, one way or the other, the then handlers are setup on P1 right away by calling the then function. P1 will keep these functions in its safe keep until it is fulfilled. As part of the "then" setup P1 assigns a new P2 which is set to be fulfilled when the P1's then handlers are finished. Finsihed means right away or asynchronously depending on how those handlers are programmed.

P2 is smart enough to know whether the then handlers that resulted in P2 returns another promise or not.

Anyway what results is a hierarchy of promises that can be setup to be chained through their then handlers.

Each then is invoked after the completion of the previous then, be it sync or async.

satya - 5/18/2019, 2:14:23 PM

Arrow functions in Javascript

Arrow functions in Javascript

Search for: Arrow functions in Javascript

satya - 5/18/2019, 2:17:20 PM

Here is how you define a simple array in JS


var materials = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

satya - 5/18/2019, 2:42:11 PM

Equivalence


elements.map(function(element) {
  return element.length;
}); // this statement returns the array: [8, 6, 7, 9]

// The regular function above can be 
// written as the arrow function below
elements.map((element) => {
  return element.length;
}); // [8, 6, 7, 9]

satya - 5/18/2019, 2:43:09 PM

It can be shortened to


elements.map(element => element.length); // [8, 6, 7, 9]

//essentially implying the return statement and 
//function body

satya - 5/18/2019, 2:45:27 PM

The mysterious this

An arrow function does not have its own this. The this value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching for this which is not present in current scope they end up finding this from its enclosing scope.

Thus, in the following code, the this within the function that is passed to setInterval has the same value as this in the lexically enclosing function:

satya - 5/18/2019, 2:46:54 PM

They use Arguments of their parent

Arrow functions do not have their own arguments object. Thus, in this example, arguments is simply a reference to the arguments of the enclosing scope:

satya - 5/18/2019, 2:48:33 PM

Read up on other nuances of arrow methods here

Read up on other nuances of arrow methods here

satya - 5/18/2019, 2:50:03 PM

Arrow functions cannot be used as constructors and will throw an error when used with new


var Foo = () => {};

// TypeError: Foo is not a constructor
var foo = new Foo(); 

// Because they don't have a "this" to take in

satya - 5/18/2019, 2:50:25 PM

Arrow functions do not have a prototype property.


var Foo = () => {};
console.log(Foo.prototype); // undefined

satya - 5/18/2019, 2:55:25 PM

Javascript await

Javascript await

Search for: Javascript await

satya - 5/18/2019, 3:20:43 PM

Lets look at async first


//lets call f1 an async func
async f1() { return "a"};

var x = f1();

//x will not be "a"
//x will be an implicit Promise (object)
//So you can do

x.then(result => console.log(result))

satya - 5/18/2019, 3:22:46 PM

So with an async you are saying


//lets call f1 an async func
async doThis() { return "a"};

//Do this later

doThis();

//When the event loop get around to it
//So doThis() is scheduled to be done later

satya - 5/18/2019, 3:35:36 PM

Will async/await block a thread node.js on SOF

Will async/await block a thread node.js on SOF

satya - 5/18/2019, 3:40:35 PM

The above is a great read (and surprising): summary here

Quote: So, while the whole interpreter doesn't block (other Javascript events can still be serviced), the execution of the specific async function that contains the await statement was suspended until the promise that was being awaited resolved. What's important to understand is step 5 above. When the first await is hit, the function immediately returns an unresolved promise and code after this function is executed (before the promise being awaited is resolved). It's for this reason that the whole interpreter is not blocked. Execution continues. Only the insides of one function are suspended until a promise is resolved.

satya - 5/18/2019, 3:41:39 PM

Interesting, so Javascript has a way to suspend a function execution while executing the rest of the code!!

Interesting, so Javascript has a way to suspend a function execution while executing the rest of the code!!

satya - 5/18/2019, 3:44:57 PM

The behavior is not ODD to the caller of that function

because that the function is expected to return only a Promise and the client knows to expect its full return using the "then" construct!

So, the code in the function block below, await() will not be executed as if it is sync call, but the not the code outside of that function.

I suppose the JS engine must have had some capabilities to do so understanding what comes, what statements come, after the await() syntactically

satya - 5/18/2019, 3:52:32 PM

No, I was a bit mistaken, what really may be happening is this, as stated in that thread


// foo is an async function that returns a promise
await foo();            
console.log("hello");

//is analogous to this:

foo().then(() => {
    console.log("hello");
});

//So the intepretter may be wrapping the code inside
//an invisible "then" 
//its possible so 
//without changing the execution environment
//That makes more sense

satya - 5/18/2019, 3:53:17 PM

So the invisible "await" is like an "invisible then", the rest follows

So the invisible "await" is like an "invisible then", the rest follows

satya - 5/18/2019, 3:54:41 PM

So there they are


Promise
Promise Chaining
Then
Arrow functions
Await
Async

satya - 5/18/2019, 3:55:59 PM

So await really means


Return now, but Do the following later

satya - 5/23/2019, 6:14:59 PM

How can I resolve a promise outside of its executor function in Javascript

How can I resolve a promise outside of its executor function in Javascript

Search for: How can I resolve a promise outside of its executor function in Javascript

satya - 5/24/2019, 5:56:09 PM

Here is an example from Github on a basic promise creation

Here is an example from Github on a basic promise creation

satya - 5/24/2019, 5:57:11 PM

Here is a more involved example from Github

Here is a more involved example from Github

satya - 5/24/2019, 5:57:21 PM

I will elaborate on these two samples later

I will elaborate on these two samples later

satya - 5/24/2019, 6:04:09 PM

Somethings about Async

1. When you tag a function as an async, it means, when called, that function will complete at some point in future

2. So the async function returns a promise object to track when that function will complete

3. The value returned by the async function will be returned "through" the Promise object

4. The async function makes a provision for "await". waiting for an internal or additional promise to complete

5. Async function "logically" returns at the point of an await

6. The await waits for that promise but will return the thread to the called

7. The promise to be waited upon can be a compound promise

8. The await mechanism allows the code to be read as if it is synchronous and sequential

9. await does not return a promise. it returns the result of the promise on which it is waiting

10. The returned result of that promise is used by subsequent lines of that function

11. It is possible to write an async function as a plain function with very similar capabilities

12. The async and the await makes that look simpler

satya - 5/24/2019, 6:07:16 PM

I can answer now why Async and await?: To work with Promise objects

Although the mechanisms of Promise, Async, and await are fairly clear from the beginning I was not able to figure out "how closely related" they were. Meaning are they independent concepts? could they be used with out the other?

It turns out async and await are keywords that allow you to use "promises" in simpler ways.

satya - 5/24/2019, 6:07:44 PM

And Promises themselves are simpler ways to use the event loop and hence to use deferred execution.

And Promises themselves are simpler ways to use the event loop and hence to use deferred execution.

satya - 5/24/2019, 6:15:09 PM

Elaboration


//Consider these utility functions

f1
f2
//one that takes longer now
//but just a regular function
//uses a promise and deferred execution
pf3
f4
f5

//Now consider working with those functions 
//to do something useful

async function af()
{
  //These will be executed right away
  f1
  f2

  //This will return right away
  //with a fake promise
  let x = await pf3

  //the following will execute
  //in the "then" portion of "pf3"
  f4(x)
  f5

  //This will go back to the promise of af()
  return "hello";
}

let y = af();
y.then (){}

//y will contain "hello" eventually
//y is a promise
//y.then is called after the "hello" is returned

satya - 5/24/2019, 6:16:04 PM

You can write "af()" as a non "async" function: you can try it. but some other day

hint: it requires chaining of the inside "then" of pf3 promise