Меню

Async/await в js

05.07.2018 - java script, ЯП

Async / Await

Вернемся к нашему коду в index.js. Будем упрощать его еще больше.

console.log('Before');
getUser(1, (user) => {
  getRepositories(user.gitHubUsername, (repos) => {
    getCommits(repos[0], (commits) => {
      console.log(commits);
    })
  })
});
console.log('After');

getUser(1)
  .then(user => getRepositories(user.gitHubUsername))
  .then(repos => getCommits(repos[0]))
  .then(commits => console.log(`Commits: `, commits))
  .catch(err => console.error(`Error:`, error));


function getUser(id) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('Reading a user from a database...');
      resolve({
        id: id,
        gitHubUsername: 'mosh'
      });
    }, 2000);
  });
}

function getRepositories(username) {
  return new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Calling GitHub API...');
    resolve(['repo1', 'repo2', 'repo3']);
  }, 2000);
});
}

function getCommits(repo) {
  return new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Calling GitHub API...');
    resolve(['commit']);
  }, 2000);

})
}

Теперь с приходом ES6 у нас появилась новая фича под названием async/await. Она помогает вам писать асинхронный код как синхронный. Перепишем наш старый промис подход под новый. Мы вызываем getUser, которая возвращает промис. Каждый раз когда вы вызваете функцию, которая возвращает промис, вы можете указать оператор await перед этой функцией, и затем получить фактический результат, как будто вызов синхронной функции. Но когда вы используете оператор await, вы должны обернуть этот вызов в async функцию. В нашем конкретном примере, оберенем наши await функции, функцией displayCommits с модификатором async и вызовем её чуть ниже. Она возвращает Promise, это означает, что промис, который fulfilled (выполнен), не возвращает значение — он void. Это говорит нам о том, что asyc/await это надстройка над промисами.

async function displayCommits() {
    try{
    const user = await getUser(1);
    const repos = await getRepositories(user.gitHubUsername);
    const commits = await getCommits(repos[0]);
    } catch (err) {
        console.error("Error ", err);
    }
    console.log(commits);
}

Внутри, когда движок js выполняет этот код, он преобразует await во что то типа как в then. Код выглядит как синхронный, но всё еще выполняется асинхронно.

Когда мы используем async/await — у нас недоступен метод catch, как в промисах. Поэтому нам следует использовать try-catch конструкцию

Метки: , , ,

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *