[英]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
而不是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))
如果_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.