Javascript Promises: як і чому

4 хв. читання

Проміси (promises, обіцянки) це саме та маленька магічна штука, що дуже корисна при розробці, якщо ви вмієте їх готувати, звісно. Відразу після знайомства з ними я не розумів що тут і до чого, але тепер, коли я усвідомив наскільки це корисний інструмент, я хочу щоб і в інших розробників був короткий і корисний гайд.

Чому

Проміси використовуються для того щоб контролювати асинхронний JavaScript. Мені потрібно було всередині коду мого сервера скорочувати посилання, використовуючи API bitly.com. Але проблема була в тому, що змінна, в якій знаходилась відповідь від API з коротким URL, ще не мала встановленого значення.

var theURL;
var encodedLongURI = encodeURIComponent('https://web.archive.org/web/20230322041443/https://www.youtube.com/watch?v=dQw4w9WgXcQ')
require('request')({
      url: 'https://web.archive.org/web/20230322041443/https://api-ssl.bitly.com/v3/shorten?access_token=ACCESS_TOKEN&longUrl=' + encodedLongURI
    }, function (err, res) {
     if(err) console.err(err);
      theURL = JSON.parse(res.body).data.url;
      console.log(theURL); // result:  http://bit.ly/2fmlg40
    })
console.log(theURL); // result: Undefined

Спочатку я не розумів чому воно не працює, я навіть думав що в мене зламаний інтерпретатор JS. Але все було куди простіше, остання стрічка коду виконується раніше чим прийде відповідь від сервера. Це стається тому що JavaScript не блокує виконання при деяких операціях (тому й потрібно використовувати колбеки). Першим, що прийшло на думку, було використати setTimeout(), але це погана ідея. Використовуйте колбеки або проміси.

Як

Ось базова структура використання промісів, на прикладі скрипту вище. Я покажу декілька еквівалентних шляхів використання промісів. Нижче я коротко опишу головні функції при використанні промісів.

var storedPromise = new Promise( (resolve,reject) => {
  request({
    url: 'https://web.archive.org/web/20230322041443/https://api-ssl.bitly.com/v3/shorten?access_token=ACCESS_TOKEN&longUrl=' + encodedLongURI
  }, function (err, res) {
    if(err) reject(err);
    resolve(JSON.parse(res.body).data.url);
  })
});

storedPromie.then((shortenedURL) => {
  console.log(shortenedURL);
}).catch((err) => {
 console.err(err); 
})

Також проміс можна створити за раз і присвоїти змінній:

var bitlyPromise = new Promise( (resolve,reject) => {
  request({
    url: 'https://web.archive.org/web/20230322041443/https://api-ssl.bitly.com/v3/shorten?access_token=ACCESS_TOKEN&longUrl=' + encodedLongURI
  }, function (err, res) {
    if(err) reject(err);
    resolve(JSON.parse(res.body).data.url);
  })
}).then((shortenedUrl) => {
  console.log(shortenedUrl); //http://bit.ly/2fmlg40
}).catch((err) => {
  console.err(err);
})

А ось так можна поєднати API Twitter та Bitly:

var Twitter = require('twitter');

var client = new Twitter({
  consumer_key: 'CONSUMER_KEY',
  consumer_secret: 'CONSUMER_SECRET',
  access_token_key: 'ACCESS_TOKEN_KEY',
  access_token_secret: 'ACESS_TOKEN_SECRET'
});

function urlPromiseGenerator(encodedLongURI) {
  return new Promise( (resolve,reject) => {
    request({
      url: 'https://web.archive.org/web/20230322041443/https://api-ssl.bitly.com/v3/shorten?access_token=ACCESS_TOKEN5&longUrl=' + encodedLongURI
    }, function (err, res) {
      if(err) reject(err);
      resolve(JSON.parse(res.body).data.url); // Ви можете робити з запитом будь-що, перед тім як викликати resolve
    })
  });  
}

var aPromise = urlPromiseGenerator(encodeURIComponent('https://web.archive.org/web/20230322041443/https://www.youtube.com/watch?v=y6120QOlsfU'));


aPromise.then((shortUrl) => {
  var createString = "I am currently watch " + shortUrl;
  return createString;
}).then((tweetString) => { // Note tweetString is createString I just wanted to show they didn't need to be the same name
    client.post('statuses/update', {status: "I am watchinging " + shortUrl});
}).
}).catch((err)=>{
  console.err(err);
});

Як ви бачите з прикладів, проміси мають декілька базових функцій:

  • Then

  • Resolve

  • Reject

  • Catch

Resolve

Ця функція дозволяє вам повертати значення з промісу до його методу then. Саме ця функція дозволяє вам чекати на виконання якоїсь операції (в даному випадку http-запиту).

Then

then - метод промісу, що викликається після resolve. Ви можете викликати його стільки раз, скільки потрібно, саме в нього передаються результати виконання коду всередині промісу.

Reject

Ця функція використовується, коли сталася якась помилка при виконанні. При цьому спрацьовує метод catch, а не then.

Catch

catch оброблює помилки, що сталися в процесі виконання (якщо такі були). Це дуже зручно, адже всі помилки відловлюються в одному місці, на відміну від колбеків, де це потрібно робити кожен раз.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 6.2K
Приєднався: 7 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація