JavaScript-ում promise hell-ի խնդիրը
Դուք արդեն գիտեք, որ promise-ները ստեղծվել էին callback hell-ի խնդիրը լուծելու համար: Սակայն, ժամանակի ընթացքում պարզ դարձավ, որ promise-ները նույնպես կարող են բարդ կոդ առաջացնել: Այս խնդիրը անալոգիայով կոչվեց 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();
Սակայն, արդյո՞ք ստացանք նույն բանը: Ոչ: Առաջին դեպքում յուրաքանչյուր նոր ֆունկցիա սպասում է նախորդ promise-ի ավարտին, իսկ երկրորդ դեպքում - բոլոր promise-ները կատարվում են միաժամանակ: Այս տարբերությունը էական կլինի այն դեպքում, երբ մենք հաջորդ ֆունկցիային ցանկանանք փոխանցել նախորդի կանչի արդյունքը:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();