Utangulizi wa Ahadi (Promises) katika JavaScript

Tayari unajua kuwa matumizi ya mfumo wa wito wa nyuma (callback) ya ushindani kwa urahisi husababisha hali ya callback hell. Kwa hivyo, katika JavaScript ilianzishwa mfumo mpya uitwao ahadi (promise). Wacha tujifunze mfumo huu.

Ahadi (Promise) inawakilisha kitu (object), ambacho kimoja kwa mabadiliko hupewa kitendakazi, ndani yake tunahitaji kuweka msimbo wetu usiofanana wa wakati mmoja (asynchronous code):

javascriptlet promise = new Promise(function() {
  // msimbo usiofanana wa wakati mmoja (asynchronous code)
});

Kama unavyoona, nimeandika kitu chenye ahadi katika kigeuzi promise. Mahali pengine katika msimbo naweza kutumia kigeuzi hiki kitendo then, kukiambia kitendakazi na msimbo, ambao unapaswa kutekelezwa ukimalizika msimbo usiofanana wa wakati mmoja, ulioandikwa wakati wa kuunda ahadi hii:

javascriptpromise.then(function() {
  // itatekelezwa ukimalizika msimbo usiofanana wa wakati mmoja
});

Inasikika kutatanisha, kwa hivyo wacha tuangalie kwa mfano. Hebu nina msimbo usiofanana wa wakati mmoja kama huu:

javascriptsetTimeout(function() {
  let result = [1, 2, 3, 4, 5];
}, 3000);

Hebu nataka kutatua kwake kazi yetu kuu ya ushindani: kutekeleza msimbo fulani baada ya kipima muda kukimbia. Wakati huo huo sitaki kuweka msimbo huo ndani ya kipima muda yenyewe na nataka, ili katika msimbo huu kwa namna fulani kuingie matokeo, ulioandikwa na mimi katika kigeuzi result. Kwa ujumla, tulitatua tatizo hili katika masomo yaliyopita kupitia wito wa nyuma (callbacks) na usajili. Hebu sasa tuangalie, jinsi ya kufanya hivyo kupitia ahadi.

Kwa kuanza, tunahitaji kufunika msimbo wetu usiofanana wa wakati mmoja ndani ya ahadi:

javascriptlet promise = new Promise(function() {
  setTimeout(function() {
    let result = [1, 2, 3, 4, 5];
  }, 3000);
});

Hii, hata hivyo, haitoshi. Tunapaswa kwa njia wazi kuonyesha, kwamba msimbo wetu usiofanana wa wakati mmoja umekwisha. Katika hili, itatusaidia kitendakazi maalum cha kumaliza, kinachoingia kiotomatiki katika mabadiliko ya kwanza ya kitendakazi, ikiwa imebainishwa:

javascriptlet promise = new Promise(function(resolve) { // tunabainisha mabadiliko
  setTimeout(function() {
    let result = [1, 2, 3, 4, 5];
  }, 3000);
});

Kwa kutumia kitendakazi cha kumaliza, tunaweza kwa wazi kuonyesha ahadini, kwamba msimbo usiofanana wa wakati mmoja umekwisha. Kwa hili, tunapaswa kiita kitendakazi hiki katika mahali tunapohitaji:

javascriptlet promise = new Promise(function(resolve) {
  setTimeout(function() {
    let result = [1, 2, 3, 4, 5];
    resolve(); // tumemaliza ahadi
  }, 3000);
});

Wakati huo huo, ikiwa tunataka kupeleka nje kwa namna fulani matokeo ya msimbo usiofanana wa wakati mmoja, tunaweza kupeleka kwa mabadiliko yetu ya kitendakazi cha kumaliza:

javascriptlet promise = new Promise(function(resolve) {
  setTimeout(function() {
    let result = [1, 2, 3, 4, 5];
    resolve(result); // tunapeleka matokeo
  }, 3000);
});

Inawezekana, bila shaka, kuondoa kigeuzi cha kati:

javascriptlet promise = new Promise(function(resolve) {
  setTimeout(function() {
    resolve([1, 2, 3, 4, 5]);
  }, 3000);
});

Sasa katika sehemu nyingine yoyote tunaweza kiita kitendo then cha ahadi yetu:

javascriptpromise.then(function() {
  // itafanya kazi ukimalizika ahadi
});

Matokeo ya kazi ya ahadi yataingia katika mabadiliko ya kwanza ya kitendakazi, ikiwa tutataka kuibainisha:

javascriptpromise.then(function(result) {
  console.log(result); // itaonyesha orodha (array) yenye matokeo
});
Задание 1

Tengeneza ahadi, ndani yake itakuwa na kucheleweshwa kwa 5 sekunde, baada ya hapo ahadi inapaswa kutekelezwa, kwa matokeo yake kurudisha maandishi fulani. Onyesha maandishi haya kwenye skrini.