Автор оригинала: FreeCodeCamp Community Member.
Обещания в JavaScript являются одним из мощных API, которые помогают нам делать асинхронизацию.
Обещание. Все занимаются асинхронизацией на следующий новый уровень, поскольку оно поможет вам объединить группу обещаний.
Другими словами, я могу сказать, что это поможет вам делать параллельные операции (иногда бесплатно).
Предпосылки:
Вы должны знать, что такое Обещание в JavaScript.
Что такое обещание. Все?
Обещание. Все на самом деле является обещанием, которое принимает массив обещаний в качестве ввода (свидетельства). Затем он решается, когда все обещания будут решаться или любой из них отвергается.
Например, предположим, что у вас есть десять обещаний (Async Operation для выполнения сетевого вызова или соединения базы данных). Вы должны знать, когда все обещания будут решаться или вам придется ждать, пока все обещания не разрешаются. Таким образом, вы проходите все десять обещаний обещать. Все. Тогда, пообещай. Все, как обещание будет решено после того, как все десять обещаний будут решаться или любой из десяти обещаний отклонен с ошибкой.
Давайте увидимся в коде:
Promise.all([Promise1, Promise2, Promise3]) .then(result) => { console.log(result) }) .catch(error => console.log(`Error in promises ${error}`))
Как видите, мы передаем массив для обещания. Все. И когда все три обещания будут решены, обещание. Все разрешается, а выход утешен.
Давайте посмотрим пример:
// 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"]
В приведенном выше примере PROUTION.ALL Rallvates после 2000 мс и вывод утешается как массив.
Одна интересная вещь о том, чтобы пообещать. Все заключается в том, что порядок обещаний поддерживается. Первое обещание в массиве будет разрешено к первому элементу выходного массива, второе обещание будет вторым элементом в массиве вывода и так далее.
Давайте посмотрим другой пример:
// 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"]
Из приведенного выше примера ясно, что обещание. Все ждет до тех пор, пока все обещания нерешится.
Посмотрим, что произойдет, если какой-либо из обещаний отклонены.
// 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.
Как видите, если один из обещаний терпит неудачу, то все остальные обещания терпят неудачу. Тогда обещайте. Все остаются отклонены.
Для некоторых используйте случаи, вам это не нужно. Вам необходимо выполнить все обещания, даже если некоторые потерпели неудачу, или, возможно, вы можете справиться с неудачными обещаниями позже.
Давайте посмотрим, как справиться с этим.
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
Использовать случаи обещания. Все
Предположим, что вы должны выполнить огромное количество асинхронных операций, таких как отправка объемных маркетинговых электронных писем на тысячи пользователей.
Простой псевдо код будет:
for (let i=0;i<50000; i += 1) { sendMailForUser(user[i]) // Async operation to send a email }
Приведенный выше пример простой. Но это не очень исполнительно. Стек станет слишком тяжелым, и в одно точку времени JavaScript будет иметь огромное количество открытого HTTP-соединения, которое может убить сервер.
Простой подход исполнителя будет делать это в партиях. Возьмите первые 500 пользователей, вызвайте почту и подождите, пока все подключения HTTP не будут закрыты. А затем возьмите следующую партию, чтобы обработать ее и так далее.
Давайте посмотрим пример:
// Async function to send mail to a list of users. const sendMailForUsers = async (users) => { const usersLength = users.length for (let i = 0; i < usersLength; i += 100) { const requests = users.slice(i, i + 100).map((user) => { // 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)
Давайте рассмотрим другой сценарий: вы должны создать API, который получает информацию из нескольких сторонних API и объединяет все ответы от API.
Обещание. Все это идеальный способ сделать это. Давайте посмотрим, как.
// 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 = `https://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 }] */
В заключение, обещание. Все лучшее способ сочувствовать группу обещаний одному обещанию. Это один из способов достижения параллелизма в JavaScript.
Надеюсь, вам понравилась эта статья. Если вы сделали, пожалуйста, хлопайте и поделитесь этим.
Даже если вы этого не сделали, это нормально, вы можете сделать это в любом случае: P