Avoid the headaches

Make your asynchronous code look synchronous!

Jordane Grenat @JoGrenat


Slides : async-sync.surge.sh

My portrait
JavaScript Elm Java
I love TV shows!

Promises

Promises

Promises

   
myAsyncCall()  
  .then(data => console.log(data));  
                        

  
myAsyncCall()  
  .catch(err => console.error(err));
                        

Promises


function giveAsynCall() {
  return new Promise((resolve, reject) => {
    myAsyncCallWithCallback((err, data) => {
      if(err) {
        reject(err);
      } else {
        resolve(data);
      }
    });
  });
}


                        

A secret about Promises
(that shouldn't be one)

then() always returns a Promise!

   
myAsyncCall()  
  .then(/* ... */)  
  .then(/* ... */)  
  .then(/* ... */)  
  .catch(/* ... */)  
  //...
                        

Promises & Chaining

   
myAsyncCall()  
  .then(data => data.user)  
  .then(user => console.log(user));
                        

Promises & Chaining with... Promises !

   
myAsyncCall()  
  .then(userId => getUserAsync(userId))  
  .then(user => console.log(user))
  .catch(error => console.error(error));
                        

Promises in parallel

   
Promise.all([promise1, promise2, ...])
  .then(data => {
    console.log(data[0], data[1]);
  });
                        

Other Promise methods

   
Promise.race([promise1, promise2, ...]); 
// first resolved / rejected
                        

   
Promise.resolve(value); 
// immediatly-resolved promise
                        

   
Promise.reject(error); 
// immediatly-rejected promise
                        

Generators

   
function *myGenerator() {  
  yield 1;  
  yield 2;
}
                        

const it = myGenerator();
console.log(it.next().value); // 1
console.log(it.next().value); // 2
                        

2-way communication

   
function *myGenerator() {  
    const value = yield 1;  
    yield 2;
    yield value;
}
                        

const it = myGenerator();
console.log(it.next().value); // 1
console.log(it.next('Hello').value); // 2
console.log(it.next().value); // 'Hello'
                        

2-way communication with errors

   
function *myGenerator() {  
  try {
    yield 1;
  } catch(err) {
    console.error(`Error: ${err}`);
  }
}
                        

const it = myGenerator();
console.log(it.next().value); // 1 
it.throw('SomeError'); // Error: SomeError
                        

Generators and Promises

   
function *myGenerator() {  
  const user = yield getUserAsync();
  console.log(user);
}
                        

const it = myGenerator();
const promise = it.next().value;
promise.then(it.next)
    .catch(it.throw);
                        

Generators and Promises with Coroutines

   
co(function*() {  
  const user = yield getUserAsync();
  console.log(user);
});
                        

Async functions

   
async function myFunction() {  
  const user = await getUserAsync();
  console.log(user);
}

myFunction();
                        

In ES2017: Now done and safe to use!

Async generator functions


async function* readLines(path) {
  let file = await fileOpen(path);

  try {
    while (!file.EOF) {
      yield await file.readLine();
    }
  } finally {
    await file.close();
  }
}
                        

Async generator functions


for await (const line of readLines(filePath)) {
  console.log(line);
}
                        

Proposal at stage 3

What's missing?


document.querySelector('.my-input')
    .addEventListener('input', event => {
        // Multiple events
    });
                        

Single value Multiple values
Promise ???

Observables

An Observable is an asynchronous data stream

Observable

Observables


const source = Observable
  .fromEvent(input, 'input');

source.subscribe(event => {
  console.log('Input content changed!', event);
});
                        

Observables


myObservable.subscribe(() => {});
                        


Observable.of(...items);
                        


Observable.from(observable);
                        

Stage 1 and really basic... So let's go with RxJS!

Reactive Programming

We progressively transform our data / events to fit our needs

Reactive Programming


const stream = Observable
  .fromEvent(input, 'input');

stream.map(event => event.target.value)
  .subscribe(value => {
    console.log('The value is now ' + value);
  });
                        

Links