Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对第二个异步函数的条件调用,基于在第一个异步函数之前收集的数据_Javascript_Node.js_Asynchronous_Es6 Promise - Fatal编程技术网

Javascript 对第二个异步函数的条件调用,基于在第一个异步函数之前收集的数据

Javascript 对第二个异步函数的条件调用,基于在第一个异步函数之前收集的数据,javascript,node.js,asynchronous,es6-promise,Javascript,Node.js,Asynchronous,Es6 Promise,我在数组中有一些数据 let data = ['firstData', 'secondData']; 第一个对象(firstData)始终存在,第二个数据可以为空。所以我总是用它来调用我的异步函数,比如: myAsyncFunction(data[0]).then(result => { //do something here }); 如果data[1]存在,我想用data[1]调用myAsyncFunction 我目前的解决方案是嵌套承诺。像这样: myAsyncFuncti

我在数组中有一些数据

let data = ['firstData', 'secondData'];
第一个对象(firstData)始终存在,第二个数据可以为空。所以我总是用它来调用我的异步函数,比如:

myAsyncFunction(data[0]).then(result => {
    //do something here
});
如果
data[1]
存在,我想用
data[1]
调用
myAsyncFunction

我目前的解决方案是嵌套承诺。像这样:

myAsyncFunction(data[0]).then(result => {
    return result;
}).then(result => {
    if(data[1] !== null){
        myAsyncFunction(data[1].then(resultTwo => {
        //dostuff with data
      });
    }
});
我真的不喜欢这个解决方案,但它确实有效。这一定是一个更好的方法<代码>结果始终是一个对象。我尝试了
承诺。所有的
都失败了。我认为这是某种“比赛条件”的问题(我在这里如履薄冰)

我目前的解决方案是唯一的吗

以下是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);
     });
});
myAsyncFunction(personData){
返回新承诺((解决、拒绝)=>{
//Assingen私有变量
secondAsyncFunction(somePersonData)。然后(结果=>
{
//做一些同步的事情
返回someNewData;//不是承诺
})
.然后(第三次同步功能)
。然后(数据=>{
解析(数据);
})
.catch(错误=>{
拒绝(错误);
});
});

假设在承诺结果之前静态地知道
数据
,您不需要将条件放入
然后
回调中-您可以使整个链接有条件:

var promise = myAsyncFunction(data[0]);
if(data[1] !== null){
    promise.then(result =>
        myAsyncFunction(data[1])
    ).then(resultTwo => {
        //dostuff with data
    });
}

一般来说,请注意嵌套并不是一件坏事,当您想要分支控制流时,它是必需的。只是不要忘记总是
从所有(回调)函数返回您的承诺。

您可以简单地执行以下操作:

const stuffOnlyRelatedToSecondData=result2=>/*做点什么*/
myAsyncFunction(数据[0])。然后(结果=>{
如果(数据[1]==null){return null}
返回myAsyncFunction(数据[1])。然后(stuffOnlyRelatedToSecondData)
})。然后(/*在[1]或[1,2]*/)之后要执行的任何操作。
被设计为在数组中有动态数量的承诺时使用,并且您希望将它们组合成一个承诺,该承诺在数组中的所有承诺都已解决时解决

根据您的用例,您应该能够这样使用它:

data = data.filter(x => x !== null);

Promise.all(data.map(myAsyncFunction)).then((results) => {
    const [resultOne, resultTwo] = results;
    if (resultTwo) {
        // handle resultTwo
    }
    // handle resultOne
});

所以我有几个问题…您的if语句正在检查它是否不等于null…这是否意味着您的数组可能是data=[“firstData”,null]?此外,您可能希望尝试使用Promise.map做一些事情。您好!对了,data[1]有时可能为null。我没有使用blubird,我使用的是ES6 promises。我认为这有区别(?)。如果您只是想知道它们什么时候都完成了,并且它们可能是空的,那么您可以从数据数组中创建一个映射,如下所示……让data_promises=data.map(function(data){return data?myAsyncFunction(data):Promise.resolve();});然后调用Promise.all(data_promises);。这几乎可以检查该值是否存在(空当然是假的)并将创建一个承诺,如果该承诺为空,将立即解决。如果您可以在尝试
承诺时共享错误消息或代码。所有
,将不胜感激。如果存在竞争条件,是否意味着第一个承诺必须在第二个承诺开始之前完成?我没有收到任何错误消息。但我有两个目标问题是这两个对象都是基于第二个对象(数据[1])的数据。当我使用Promise.all时,我只得到基于第二个值的结果。正如我所说的,我认为这与竞争条件有关。在这种情况下,可能会有Promise泄漏(即,您的异步函数在实际执行完成之前自行解析/拒绝)哦……这就可以解释了。找出是否有任何承诺泄漏的最佳方法是什么?@4castle,您可能需要执行
data.filter(i=>i).map(myAsyncFunction)
。因为
myAsyncFunction
不应在
data[x]时执行
null
但没有看到函数体,我不能确定,但是没有
承诺。所有
将始终执行内部的所有承诺,并返回其已解决的回调。除非其中任何
拒绝
抛出
异常,在这种情况下,
承诺。所有
将在第一次拒绝失败,并且没有成功(
挂起
完成
)将被报告我尝试了编辑中的代码。我理解重新包装代码的方式是不必要的。但问题是,使用相同的值调用secondAsyncFunction两次。即使在返回secondAsyncFunction之前,所有值都是正确的。Hm。我在返回secondAsyncFunction之前创建了一个变量(让我们称之为y)。如果我是console.log(y) (在secondAsyncFunction内部)我得到了属性.prop的正确值(例如)。但是当我控制台.log(y.prop)时-我得到了错误的值?@mintermasher听起来您需要进行更多的调试,直到您可以用实际代码将问题缩小到一个。