For循环内的承诺

时间:2018-11-13 17:46:45

标签: javascript promise

我有此代码:

 _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)})

但这不起作用,代码总是转到最后一个陷阱。

更新

getSupport()的格式为

function _getSupport(param = {}) {       

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

5 个答案:

答案 0 :(得分:2)

问题出在这里

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()

答案 1 :(得分:1)

这个答案几乎与其他答案相同,只有2​​美分:您可以使用.map代替forEachpush

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))

答案 2 :(得分:0)

如果您_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

答案 3 :(得分:0)

有时嵌套的promise会产生问题。

我们需要将promise累积到一个数组中,以便您可以全部返回它们。 这就是为什么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)})

答案 4 :(得分:0)

尽管所有答案都刺激了我的大脑,但都没有达到预期效果。 我发现的唯一解决方案源自此answer

 _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);
  });