Обещания внутри петли - PullRequest
       3

Обещания внутри петли

0 голосов
/ 13 ноября 2018

У меня есть этот код:

 _getSupport()
.then((data) => {                   
    _getSupport(data[0])
        .then(() => _getSupport(data[1])    
})
.catch(e => {
      console.log(e);
});

_getSupport вернуть Promise. Моя цель - снова вызвать _getSupport для значений, возвращаемых в первый раз. Итак, я подумал:

_getSupport()
.then((data) => {       
    let a = [];
    data.forEach(element => {
        a[element] = _getSupport(element)   
      });
      Promise.all(a).then().catch(e => {
      });
 })
 .catch( e => {console.log(e)})

Но это не работает, код всегда идет к последнему улову.

UPDATE

getSupport() имеет эту форму

function _getSupport(param = {}) {       

    return new Promise((resolve, reject) => {           
        remoteClient.sendRequest(request, function (data) {             
            resolve(data);
        });
    });
}    

Ответы [ 5 ]

0 голосов
/ 16 ноября 2018

Хотя все ответы стимулировали мой мозг, ни один не работал, как ожидалось.Единственное решение, которое я нашел, основано на этом ответе :

 _getSupport() 
 .then((data) => {
                let sTypes = data.parameter.supported_types || [];
                sTypes.reduce((p,value,currentIndex) => {
                    return p.then(() => _getSupport({ method: "get_supported_scale", sType: value }));
                },Promise.resolve());                    
            })          
 .catch(e => {
        logger.error(e.stack);
  });
0 голосов
/ 13 ноября 2018

Этот ответ почти идентичен другим ответам, всего два цента: вы можете использовать .map вместо forEach и push.

let getPromiseObj = data => new Promise((resolve, reject) =>
  setTimeout(
    () => resolve(data || ['No', 'truthy', 'data']),
    1000
  )
)

getPromiseObj()
  .then(res => Promise.all(res.map(getPromiseObj)))
  .then(finalRes => console.log(finalRes))
  .catch(e => console.error(e))
0 голосов
/ 13 ноября 2018

Здесь кроется проблема

let a = [];
data.forEach(element => {
  a[element] = _getSupport(element)   
});

Поскольку данные могут содержать практически все; числа, объекты, строки, что угодно, поэтому, когда вы устанавливаете a[element], вы фактически устанавливаете это конкретное свойство для массива.

a = []
a['see_this?'] = 'does this even make sense?'

Вы получаете точку.

То, что вы должны сделать, это

let a = [];
data.forEach(element => {
  a.push(_getSupport(element))
});
// or
a = data.map(element =>_getSupport(element));

и затем используйте свой Promise.all; конечно, если это фрагмент кода функции, вам нужно вернуть его, чтобы другие могли .then() на нем, поэтому return Promise.all()

0 голосов
/ 13 ноября 2018

Иногда вложенные обещания создают проблемы.

Нам нужно накапливать обещания в массив, чтобы вы могли вернуть их все.Вот почему a.push (), которая отправляет обещания в массив.

Данные в следующей функции .then () представляют собой массив ответов каждого обещания в том же порядке, в котором они были отправлены.

Добавьте console.log (data), чтобы увидеть, по каким значениям вы продолжаете итерацию. Если данные не могут быть повторены, то это может привести к ошибке.

Попробуйте выполнить функцию "_getSupport ()" по отдельности и посмотреть, если вы получаете какие-либо ошибки, если нет, то попробуйте мой код, он будет работать.

    _getSupport()
     .then((data) => {       
         let a = [];
         data.forEach(element => {
         a.push(_getSupport(element))
         });
         return Promise.all(a)
      })
     .then((data) => {
      // If it returns an array of elements then this data will be
      // [[0,1,2],[1,2,3] ...] based on the number of elements returned in 
      // first call
      })
     .catch( e => {console.log(e)})
0 голосов
/ 13 ноября 2018

Если вы _getSupport верны и не выдает ошибку, для начала вы также можете изменить свой код на что-то вроде этого:

_getSupport()
  .then(data => {
    let a = [];
    data.forEach(element => a[element] = _getSupport(element))
    return Promise.all(a).then().catch(e => {})
  })
  .catch(e => console.log(e))

Где вы также return последний Promise.all

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...