Увядзенне ў промісы ў JavaScript
Вы ўжо ведаеце, што выкарыстанне колбэк-мадэлі асінхроннасці лёгка прыводзіць да сітуацыі callback hell. Таму ў JavaScript была ўведзена новая мадэль пад назвай промісы (promise, абяцанне). Давайте вывучым гэтую мадэль.
Проміс уяўляе сабой аб'ект, у які параметрам перадаецца функцыя, унутры якой трэба размяшчаць наш асінхронны код:
let promise = new Promise(function() {
// асінхронны код
});
Як вы бачыце, я запісаў аб'ект з промісам
у зменную promise. У нейкім іншым
месцы кода я магу прымяніць да гэтай зменнай
метад then, перадаўшы ў яго функцыю
з кодам, які павінен быць выкананы па
завяршэнні асінхроннага кода, напісанага
пры стварэнні дадзенага проміса:
promise.then(function() {
// выканаецца пры завяршэнні асінхроннага кода
});
Гучыць заблытана, таму давайте паглядзім на прыклад. Хай у мяне ёсць вось такі асінхронны код:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
Хай я хачу вырашыць для яго нашу асноўную
задачу асінхроннасці: выканаць некаторы
код пасля спрацоўвання таймера. Пры гэтым
я не хачу размяшчаць гэты код у самым таймеры
і хачу, каб у гэты код як-трапіў вынік,
напісаны мною ў зменнай result.
Увогуле, мы вырашалі гэтую задачу ў папярэдніх
уроках праз колбэкі і падпіскі. Давайте
цяпер паглядзім, як гэта зрабіць праз промісы.
Для пачатку трэба абгарнуць наш асінхронны код у проміс:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Гэтага, аднак, не дастаткова. Мы павінны у яўным выглядзе паказаць, што наш асінхронны код завяршыўся. У гэтым нам дапаможа спецыяльная функцыя завяршэння, аўтаматычна якая трапляе ў першы параметр функцыі, калі ён паказаны:
let promise = new Promise(function(resolve) { // паказваем параметр
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
З дапамогай функцыі завяршэння мы можам яўна паказаць промісу, што асінхронны код завяршыўся. Для гэтага мы павінны выклікаць гэтую функцыю ў патрэбным нам месцы:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // завяршаем проміс
}, 3000);
});
Пры гэтым, калі мы хочам перадаць вонкі які-небудзь вынік асінхроннага кода, мы можам перадаць яго параметрам нашай функцыі завяршэння:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // перадаем вынік
}, 3000);
});
Можна, вядома ж, пазбавіцца ад прамежкавай зменнай:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
Цяпер у любым іншым месцы мы можам выклікаць
метад then нашага проміса:
promise.then(function() {
// спрацуе па завяршэнню проміса
});
Вынік працы проміса трапіць у першы параметр функцыі, калі мы пажадаем яго паказаць:
promise.then(function(result) {
console.log(result); // вывядзе масіў з вынікам
});
Зрабіце проміс, унутры якога будзе затрымка
ў 5 секунд, пасля якой проміс павінен
выканацца, сваім вынікам вярнуўшы які-небудзь
тэкст. Вывядзіце гэты тэкст на экран.