Promise Hell-ის პრობლემა JavaScript-ში
თქვენ უკვე იცით, რომ პრომისები შეიქმნა იმისთვის, რომ გადაეჭრათ callback hell-ის პრობლემა. თუმცა, დროთა განმავლობაში აღმოჩნდა, რომ პრომისებსაც შეუძლიათ გამოიწვიონ რთული კოდი. ეს პრობლემა ანალოგიით დაერქვა promise hell.
მოდით განვიხილოთ ეს პრობლემა კოდის მაგალითებზე.
დავუშვათ, გვაქვს ფუნქცია getSmth,
რომელიც იღებს პარამეტრს და აბრუნებს შედეგს
ამ პარამეტრის მიხედვით:
function getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
ამ შემთხვევაში ჩვენ ვიმიტირებთ რაიმე სასარგებლო ოპერაციას (მაგალითად, სერვერიდან მონაცემების მიღებას). იმიტირებისთვის ჩვენ უბრალოდ პარამეტრად ვაწვდით რიცხვს და ერთი წამის შემდეგ ვაბრუნებთ ამ რიცხვის კვადრატს.
მოდით ახლა გამოვიყენოთ ჩვენი ფუნქცია
getSmth სხვა ფუნქციის შიგნით:
function func() {
getSmth(2).then(res => {
console.log(res); // გამოიტანს 4-ს
});
}
func();
პირველი პრობლემა
ერთმანეთის მიყოლებით განლაგებული
then კონსტრუქციები ართულებს კოდის გაგებას:
function func(){
getSmth(2).then(res1 => {
// ვაკეთებთ რაღაცას
}).then(res2 => {
// ვაკეთებთ რაღაცას
}).then(res3 => {
// ვაკეთებთ რაღაცას
}).then(res4 => {
// ვაკეთებთ რაღაცას
}).then(res5 => {
// ვაკეთებთ რაღაცას
}).then(res6 => {
// ვაკეთებთ რაღაცას
});
}
func();
მეორე პრობლემა
არსებობს სხვა ხასიათის პრობლემაც. დავუშვათ ახლა გვსურს ჩვენი ფუნქციის ორჯერ გამოყენება, შემდეგ კი შედეგების შეკრება. შედეგად ჩვენ მივიღებთ ასეთ კოდს:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // გამოიტანს 13-ს
});
});
}
func();
უკვე წააგავს callback hell-ს, არა? დავამატოთ კიდევ ერთი ფუნქციის გამოძახება - კოდი გაუარესდება:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
შესაძლებელია, რა თქმა უნდა, გამოვიყენოთ Promise.all:
function func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
თუმცა, მივიღეთ თუ არა იგივე? არა! პირველ შემთხვევაში ყოველი ახალი ფუნქცია ელოდება წინა პრომისის დასრულებას, ხოლო მეორე შემთხვევაში - ყველა პრომისი სრულდება ერთდროულად. ეს განსხვავება მნიშვნელოვანი იქნება იმ შემთხვევაში, როდესაც ჩვენ მომდევნო ფუნქციას გვსურს გადავცეთ წინახის გამოძახების შედეგი:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();