繁体   English   中英

For循环中的承诺

[英]Promises Inside a For Loop

我有这个代码:

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

这就是问题所在

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

这个答案几乎与其他答案相同,只有两分钱:你可以使用.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))

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

有时嵌套的承诺会产生问题。

我们需要将promises累积到一个数组中,以便您可以将它们全部返回。 这就是为什么a.push()会将promises推送到数组。

下一个.then()函数中的数据是每个promise的响应数组,它们的推送顺序相同。

添加console.log(数据)以查看您正在进一步迭代的值。如果数据无法迭代,则可能会抛出错误。

尝试单独执行“_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)})

虽然所有答案都刺激了我的大脑,但都没有按预期工作。 我发现的唯一解决方案源于这个答案

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM