Проміси (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
оброблює помилки, що сталися в процесі виконання (якщо такі були). Це дуже зручно, адже всі помилки відловлюються в одному місці, на відміну від колбеків, де це потрібно робити кожен раз.
Ще немає коментарів