我在数组中有一些数据。
let data = ['firstData', 'secondData'];
第一个对象(firstData)始终存在,secondData可以为null。所以我总是使用它来调用我的异步函数,如:
myAsyncFunction(data[0]).then(result => {
//do something here
});
如果data[1]
存在,我想用myAsyncFunction
致电data[1]
。
我目前的解决方案是嵌套承诺。像这样:
myAsyncFunction(data[0]).then(result => {
return result;
}).then(result => {
if(data[1] !== null){
myAsyncFunction(data[1].then(resultTwo => {
//dostuff with data
});
}
});
我不太喜欢这个解决方案,但确实有效。这一定是更好的方式。 result
始终是一个对象。我试过Promise.all
,但它不起作用。我认为这是"竞争条件"的一个问题。某种形式(我在这里薄冰)。
我目前的解决方案是唯一的吗?
以下是myAsuncFunction的样子:
myAsyncFunction(personData){
return new Promise<any> ((resolve, reject) => {
//Assingen private variables
secondAsyncFunction(somePersonData).then(result =>
{
//Do some sync stuff
return someNewData; //not a promise
})
.then(thirdAsyncFunction)
.then(data => {
resolve(data);
})
.catch(error => {
reject(error);
});
});
答案 0 :(得分:1)
Promise.all
旨在在数组中具有动态数量的promise时使用,并且您希望将它们组合成一个promise,该promise在数组中的所有promise都已解析时解析。
根据您的使用案例,您应该能够像这样使用它:
data = data.filter(x => x !== null);
Promise.all(data.map(myAsyncFunction)).then((results) => {
const [resultOne, resultTwo] = results;
if (resultTwo) {
// handle resultTwo
}
// handle resultOne
});
答案 1 :(得分:0)
鉴于data
在承诺结果之前已经静态知道,您不需要将条件置于then
回调中 - 您可以使整个链条成为条件:
var promise = myAsyncFunction(data[0]);
if(data[1] !== null){
promise.then(result =>
myAsyncFunction(data[1])
).then(resultTwo => {
//dostuff with data
});
}
一般情况下,请注意嵌套不是坏事,当您想要分支控制流时需要它。只是不要忘记永远return
所有(回调)函数的承诺。
答案 2 :(得分:0)
你可以简单地做:
const stuffOnlyRelatedToSecondData = result2 => /*do something*/
myAsyncFunction(data[0]).then(result => {
if (data[1] === null) {return null}
return myAsyncFunction(data[1]).then(stuffOnlyRelatedToSecondData)
}).then(/*Anything to do after [1] or [1,2]*/)
&#13;
这样你可以使用相同的链,两种可能的情况如下:
myAsyncFunction(data[0]) --> END
myAsyncFunction(data[0]) --> myAsyncFunction(data[1]) --> END
似乎myAsyncFunction
可能有承诺泄漏,请尝试使用类似的东西:
const myAsyncFunction = personData => {
//Assigning private variables
return secondAsyncFunction(somePersonData).then(result => {
//Do some sync stuff
return someNewData; //not a promise
})
.then(thirdAsyncFunction)
}
我们可以这样写,因为secondAsyncFunction
启动了一个新的Promise,因此我们不需要另一个Promise包装器。并且catch可以放在执行myAsyncFunction