Идем к синхронному flow в асинхронном мире JavaScript

Александр Павлов
AndersenLab

Весь доклад можно выразить 1 слайдом

С чего все началось

2014г - веб сайт на express  с DAU ~ 300.000

2015г - переход на "обещания" и генераторы

2016г - await с флагом на внутренних проектах

2017г - полная поддержка async/await

Callback подход

...

      $.get('/endpoint/...', function (res) {

        ...

      });

    });

  });

});

...

Legasy монолитный проект

Распространение обещаний (Promise)

 

Объекты обещаний позволили уменьшить уровень вложенности в коде и избавиться от повсеместных callback вызовов.

Распространение обещаний (Promise)

 

Новый код стали писать используя обещания

Promise

fetch('/endpoint/...')

  .then(function (response) {

    return response.json();

  })

  .then(function (data) {

    ...; // some work

  })

  .catch(function (error) {

    console.log('Request error: ', error);

   });

Iterator

- next() : IteratorResult

- return()  

- throw()

Iterator

let arr = [1, 2, 3];
let it = arr[Symbol.iterator]();

it.next(); // { value: 1, done: false}

it.next(); // { value: 2, done: false}

it.next(); // { value: 3, done: false}

it.next(); // { value: undefined, done: true}

Generator

Функция, которая позволяет делать возврат значения несколько раз

 

- Приостановка функции и возможность передать сообщение из генератора

 

- Возможность продолжить выполнение c прерванного места и передать сообщение в функцию

Generator

let generator = function* () {

    yield 1;

    yield 2;

    yield 3;

    return 4;

};

Generator

let iterator = generator();


iterator.next(); // yield 1 => {value: 1, done: false }

iterator.next(); // yield 2 => {value: 2, done: false }

iterator.next(); // {value: 3, done: false }

iterator.next(); // return 4 => {value: 4, done: true }

iterator.next(); // {value: undefined, done: true }

let generator = function () {

    let step = 0;

    let nextState = function (data) {

        switch (step) {

           case 0:    return 42;

           case 1:    console.log(data);  return 56;

       }

    };

    return {

        next: function (data) {

            return { value: nextState(data), done: ++step === 2 }

        }

    };

}

 

Async - Await

Более простой и быстрый yield c точки зрения flow.

(async () => {
    let response = await fetch('/endpoint');
})();

Рефакторинг

- Не останавливаем процесс разработки

- Можно комбинировать все подходы

- Можно переписывать маленькими кусочками

- Делаем все проще :)

А ты попробуешь это у себя?

Что дальше?

Что дальше?

- Async generator

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

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

Профит

- Переход от любого состояния к любому состоянию

 

- Возможность запуска кода на более старых  environment посредством преобразования кода
 

- Читаем код сверху вниз, слева напрово
 

Профит

Ссылки

https://expressjs.com/
https://www.npmjs.com/package/co-express
https://github.com/tc39/proposal-async-iteration
https://kangax.github.io/compat-table/esnext/
https://alexpts.ru/posts/57b7508727fa593fc7273bf2/

Вопросы?

Хороший вопрос :) Дай пять

Спасибо

Александр Павлов
AndersenLab

Идем к синхронному flow в асинхронном мире nodeJs

By Alex Pavlov

Идем к синхронному flow в асинхронном мире nodeJs

  • 927