Дефекты Promise.all

JavaScript

предисловие

Promiseдаes6Новый синтаксис используется для обработки асинхронных запросов, которые ранее не были решены.Promiseад обратного звонка.PromiseЕсть несколько API,Promise.resolve,Promise.reject,Promise.all,Promise.race. Что касается множественной асинхронной обработки, мы можем использоватьPromise.all,ноPromise.allтолько во всехpromiseВсеresolveбудет вызван, когда.thenобратный вызов успеха в . Иногда несколько запросов неизбежно терпят неудачу, мы хотим бытьPromise.allсерединаpromiseобъектrejectФункция обратного вызова также может быть вызвана в случае сбоя.Что мне делать в это время?

Начало

Давайте сначала разберемсяPromise.allПрименение.

 Promise.all([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)])
.then(res => console.log(res),err=>console.log(err))
// [1, 2, 3]

 Promise.all([Promise.reject(1), Promise.resolve(2), Promise.resolve(3)])
.then(res => console.log(res),err=>console.log(err))
// 1

Promise.allпередается в несколькихpromiseМассив объектов. все в массивеpromiseпечатать только в случае успехаres, который будет печататься всякий раз, когда произойдет сбойerr.

Мы хотим распечатать всю информацию, даже если это не удастся, как нам это сделать? очень просто, используйте.thenпотому что.thenтакже возвращаетpromiseобъект, будь тоresolveещеrejectбудет выполнять.then. вернутьpromiseобъект становитсяresovleСостояние.

 Promise.all([Promise.reject(1).then((res) => ({ status: 'ok', res }), (err) => ({ status: 'not ok', err })), 
Promise.resolve(2).then((res) => ({ status: 'ok', res }), (err) => ({ status: 'not ok', err })), 
Promise.resolve(3).then((res) => ({ status: 'ok', res }), (err) => ({ status: 'not ok', err }))])
.then(res => console.log(res),err=>console.log(err))
//[ {status: "not ok", err: 1},{status: "ok", res: 2},{status: "ok", res: 3}]

Это отпечатывает всю информацию, даже еслиPromise.allимеютrejectусловие.

Оптимизированная упаковка

Теперь это громоздко писать, каждый в каждом массивеpromiseнаписать то же самое.then. мы можем поставить.thenВытаскивать. Инкапсулируйте его как функцию, а затем используйтеmapметод, для каждогоpromise .then, затем верните новый массив.

function handlePromise(promiseList) {
    return promiseList.map(promise =>
      promise.then((res) => ({ status: 'ok', res }), (err) => ({ status: 'not ok', err }))
    )
  }

звони вот такpromise.all, ты можешь написать:

Promise.all(handlePromise([Promise.reject(1),Promise.resolve(2),Promise.resolve(3)]))
.then(res => console.log(res),err=>console.log(err))

Это тот же эффект.

Даже мы можем написатьPromise.allSettledметод:

  Promise.allSettled2 = function (promiseList) {
    return Promise.all(handlePromise(promiseList))
  }
Promise.allSettled2 ([Promise.reject(1),Promise.resolve(2),Promise.resolve(3)]).then(res => console.log(res), err => console.log(err))

ЭтоpromiseновыйallSettledApi`, но совместимость не очень, но ничего страшного, прочитав эту статью, мы можем инкапсулировать api с той же функцией. Закончили цветение.

image.png