Kõik, mida peate teadma Promise.all kohta

JavaScripti lubadused on üks võimsamaid API-sid, mis aitavad meil Asynci toiminguid teha.

Promise.all viib Asynci toimingud uuele uuele tasemele, kuna see aitab teil lubaduste rühma koondada.

Teisisõnu võin öelda, et see aitab teil samaaegseid toiminguid teha (mõnikord tasuta).

Eeldused:

Peate teadma, mis on JavaScripti lubadus .

Mis on Promise.all?

Promise.all on tegelikult lubadus, mis võtab sisendina hulga lubadusi (korduv). Siis saab see lahendatud, kui kõik lubadused saavad lahendatud või keegi neist tagasi lükatakse.

Oletame näiteks, et teil on kümme lubadust (võrgukõne või andmebaasiühenduse sooritamine Async-operatsioonis). Peate teadma, kui kõik lubadused saavad lahendatud või peate ootama, kuni kõik lubadused lahendatakse. Nii et annate Promise.allile kõik kümme lubadust. Seejärel saab Promise.all lubadus ise lahenduse, kui kõik kümme lubadust lahendatakse või mõni kümnest lubadusest veaga tagasi lükatakse.

Vaatame seda koodis:

Promise.all([Promise1, Promise2, Promise3]) .then(result) => { console.log(result) }) .catch(error => console.log(`Error in promises ${error}`))

Nagu näete, edastame massiivi saidile Promise.all. Ja kui kõik kolm lubadust lahendatakse, lahendatakse Promise.all ja väljund lohutatakse.

Vaatame näite:

// A simple promise that resolves after a given time const timeOut = (t) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(`Completed in ${t}`) }, t) }) } // Resolving a normal promise. timeOut(1000) .then(result => console.log(result)) // Completed in 1000 // Promise.all Promise.all([timeOut(1000), timeOut(2000)]) .then(result => console.log(result)) // ["Completed in 1000", "Completed in 2000"]

Ülaltoodud näites lahendatakse Promise.all pärast 2000 ms ja väljund lohutatakse massiivina.

Promise.all-i üks huvitav asi on see, et lubaduste järjekord säilib. Massiivi esimene lubadus lahendatakse väljundmassiivi esimesele elemendile, teine ​​lubadus on väljundmassiivi teine ​​element ja nii edasi.

Vaatame veel ühte näidet:

// A simple promise that resolves after a given time const timeOut = (t) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(`Completed in ${t}`) }, t) }) } const durations = [1000, 2000, 3000] const promises = [] durations.map((duration) => { // In the below line, two things happen. // 1. We are calling the async function (timeout()). So at this point the async function has started and enters the 'pending' state. // 2. We are pushing the pending promise to an array. promises.push(timeOut(duration)) }) console.log(promises) // [ Promise { "pending" }, Promise { "pending" }, Promise { "pending" } ] // We are passing an array of pending promises to Promise.all // Promise.all will wait till all the promises get resolves and then the same gets resolved. Promise.all(promises) .then(response => console.log(response)) // ["Completed in 1000", "Completed in 2000", "Completed in 3000"] 

Ülaltoodud näite põhjal on selge, et Promise.all ootab, kuni kõik lubadused lahendatakse.

Vaatame, mis juhtub, kui mõni lubadustest tagasi lükatakse.

// A simple promise that resolves after a given time const timeOut = (t) => { return new Promise((resolve, reject) => { setTimeout(() => { if (t === 2000) { reject(`Rejected in ${t}`) } else { resolve(`Completed in ${t}`) } }, t) }) } const durations = [1000, 2000, 3000] const promises = [] durations.map((duration) => { promises.push(timeOut(duration)) }) // We are passing an array of pending promises to Promise.all Promise.all(promises) .then(response => console.log(response)) // Promise.all cannot be resolved, as one of the promises passed got rejected. .catch(error => console.log(`Error in executing ${error}`)) // Promise.all throws an error. 

Nagu näete, kui üks lubadustest ebaõnnestub, siis kõik ülejäänud lubadused ebaõnnestuvad. Siis lükatakse Promise.all tagasi.

Mõnel juhul ei vaja te seda. Peate kõik lubadused täitma ka siis, kui mõned on ebaõnnestunud, või saate ka hiljem ebaõnnestunud lubadustega hakkama.

Vaatame, kuidas sellega hakkama saada.

const durations = [1000, 2000, 3000] promises = durations.map((duration) => { return timeOut(duration).catch(e => e) // Handling the error for each promise. }) Promise.all(promises) .then(response => console.log(response)) // ["Completed in 1000", "Rejected in 2000", "Completed in 3000"] .catch(error => console.log(`Error in executing ${error}`)) view raw

Kasutage Promise.all juhtumeid

Oletame, et peate sooritama tohutu hulga Asynci toiminguid, nagu tuhandetele kasutajatele hulgimüügi turundusmeilide saatmine.

Lihtne pseudokood oleks:

for (let i=0;i<50000; i += 1) { sendMailForUser(user[i]) // Async operation to send a email }

Ülaltoodud näide on sirgjooneline. Kuid see pole eriti esitaja. Virn muutub liiga raskeks ja ühel hetkel on JavaScriptil tohutu arv avatud HTTP-ühendust, mis võib serveri tappa.

Lihtne esitusviis oleks teha seda partiidena. Võtke esimesed 500 kasutajat, käivitage meil ja oodake, kuni kõik HTTP-ühendused on suletud. Ja siis võtke järgmine partii selle töötlemiseks ja nii edasi.

Vaatame näite:

// Async function to send mail to a list of users. const sendMailForUsers = async (users) => { const usersLength = users.length for (let i = 0; i 
    
      { // The batch size is 100. We are processing in a set of 100 users. return triggerMailForUser(user) // Async function to send the mail. .catch(e => console.log(`Error in sending email for ${user} - ${e}`)) // Catch the error if something goes wrong. So that it won't block the loop. }) // requests will have 100 or less pending promises. // Promise.all will wait till all the promises got resolves and then take the next 100. await Promise.all(requests) .catch(e => console.log(`Error in sending email for the batch ${i} - ${e}`)) // Catch the error. } } sendMailForUsers(userLists)
    

Mõelgem veel ühele stsenaariumile: peate ehitama API, mis saab teavet mitmest kolmanda osapoole API-st ja koondab kõik API-de vastused.

Promise.all on ideaalne viis seda teha. Vaatame kuidas.

// Function to fetch Github info of a user. const fetchGithubInfo = async (url) => { console.log(`Fetching ${url}`) const githubInfo = await axios(url) // API call to get user info from Github. return { name: githubInfo.data.name, bio: githubInfo.data.bio, repos: githubInfo.data.public_repos } } // Iterates all users and returns their Github info. const fetchUserInfo = async (names) => { const requests = names.map((name) => { const url = `//api.github.com/users/${name}` return fetchGithubInfo(url) // Async function that fetches the user info. .then((a) => { return a // Returns the user info. }) }) return Promise.all(requests) // Waiting for all the requests to get resolved. } fetchUserInfo(['sindresorhus', 'yyx990803', 'gaearon']) .then(a => console.log(JSON.stringify(a))) /* Output: [{ "name": "Sindre Sorhus", "bio": "Full-Time Open-Sourcerer ·· Maker ·· Into Swift and Node.js ", "repos": 996 }, { "name": "Evan You", "bio": "Creator of @vuejs, previously @meteor & @google", "repos": 151 }, { "name": "Dan Abramov", "bio": "Working on @reactjs. Co-author of Redux and Create React App. Building tools for humans.", "repos": 232 }] */ 

Kokkuvõtteks võib öelda, et Promise.all on parim viis koondada lubadused ühte lubadusse. See on üks viise JavaScripti samaaegsuse saavutamiseks.

Loodetavasti see artikkel meeldis teile. Kui sa seda tegid, siis palun plaksuta ja jaga seda.

Isegi kui te seda ei teinud, on see hea, saate seda ikkagi teha: P