Javascript 如何使多个异步函数中的一个等待某个特定函数,或使其在某些特定情况下同步运行?

Javascript 如何使多个异步函数中的一个等待某个特定函数,或使其在某些特定情况下同步运行?,javascript,asynchronous,promise,async-await,rxjs,Javascript,Asynchronous,Promise,Async Await,Rxjs,在角度应用程序中,我有以下组件和服务。我在相关的div中有三个复选框,通常根据从ngOnInit中的异步api调用获得的数据选中默认复选框 我需要删除默认复选框,如果它不是作为功能的一部分购买的,并且当这种情况发生并且该复选框使用ngIf从模板中删除时,我需要选择下一个复选框作为默认值 我的特性检查服务方法是一个async方法,所以我像(async()=>{…})一样调用它,如下所示 我已经测试过了,它有时会标记下一个,但有时不会。所以我认为,由于我的新方法调用也是异步的,它们的顺序是未知的 我

在角度应用程序中,我有以下组件和服务。我在相关的div中有三个复选框,通常根据从
ngOnInit
中的异步api调用获得的数据选中默认复选框

我需要删除默认复选框,如果它不是作为功能的一部分购买的,并且当这种情况发生并且该复选框使用
ngIf
从模板中删除时,我需要选择下一个复选框作为默认值

我的特性检查服务方法是一个
async
方法,所以我像
(async()=>{…})一样调用它,如下所示

我已经测试过了,它有时会标记下一个,但有时不会。所以我认为,由于我的新方法调用也是异步的,它们的顺序是未知的

我使用async getFeatures方法从几个地方通过一个自定义的结构指令来决定对于大多数没有前提条件的情况是否渲染模板,所以我没有这样的要求,但在这种情况下,我有一个条件,所以我在异步调用之间有一个顺序

我的问题是,

  • 在这种情况下,如何同步调用
    async getFeatures(){}
  • 如何设置为getFeatures将在最后运行或在
    getPreset
    之后运行
  • @组件({
    /...
    })
    导出类组件实现OnInit{
    恩戈尼尼特(){
    //做一些事情
    this.getPreset();//异步调用
    //我的新异步函数调用
    (异步()=>{
    让utpFeature=等待这个.featureService.getFeatures(“运行计划”);
    this.utpFeatureStatus=utpFeature?utpFeature.Status:true;
    //如果没有功能,则启用下一个“FillInYourself”复选框
    this.MyForm.controls[“FillInYourself”].setValue(!this.utpFeatureStatus);
    })();
    }
    getPreset(){
    //从多个服务异步获取大量数据
    //将三个复选框之一设置为标记为默认值。
    forkJoin([getFoo,getBar,getBaz])。订阅((结果:any)=>{
    //转换结果和过程数据
    checkedUseFirstPlan(数据);//通常默认复选框
    }
    }
    checkedUseFirstPlan(数据:布尔值){
    如果(!数据){
    this.MyForm.controls[“UseFirstPlan”].setValue(true);
    返回;
    }
    this.MyForm.controls[“UseFirstPlan”].setValue(数据);
    this.MyForm.controls[“FillInYourself”].setValue(!data);
    this.MyForm.controls[“OtherPlan”].setValue(!data);
    }
    }
    //服务
    异步getFeatures(键名:string){
    //...
    等待这个.apiService.getFeatures().toPromise()。然后((结果:any)=>{
    //处理结果并获取与此键名相关的特征
    }
    返回特性;
    }
    
    这只是一个在
    wait
    帮助下执行异步函数的示例。示例中的所有3个函数都将严格按照顺序依次运行

    //使用异步
    (异步()=>{
    //职能1
    常数fn1=(val)=>{
    返回新承诺((解决、拒绝)=>{
    //在这里做些事情
    val=val+1;
    //解决结果。
    //可以从任何级别解决
    //嵌套函数的定义!
    函数nested1(){
    函数nested2(){
    解决(val);
    }
    嵌套2();
    }
    nested1();
    });
    };
    //职能2
    常数fn2=(val)=>{
    返回新承诺((解决、拒绝)=>{
    //在这里做些事情
    val=val*2;
    //解析结果
    解决(val);
    });
    };
    //职能3
    常数fn3=(val)=>{
    返回新承诺((解决、拒绝)=>{
    //在这里做些事情
    val=val+1000;
    //解析结果
    解决(val);
    });
    };
    //同步代码
    设val=5;
    val=等待fn1(val);//等待fn1解析
    val=等待fn2(val);//等待fn2解析
    val=等待fn3(val);//等待fn3解析
    控制台日志(val);
    
    })();
    谢谢@tarkh,这是否意味着
    fn2
    将始终等待
    fn1
    完成,或者当您使用
    等待fn1(val)
    然后
    等待fn2(val)
    调用时将在同一时间开始?我还知道您将第一个异步调用的结果传递到
    val=wait fn1(val);
    fn2(val)
    ,这就是使它们同步的原因吗?是的,
    await
    将暂停当前作用域的执行(父
    async
    函数,在该函数中执行
    await
    …),因此fn2将仅在执行
    resolve
    fn1函数后启动。而最后一个正常函数-
    console.log
    将仅在fn3解析后执行。因此,通过这种方式,您可以在JavaScriptAnd中创建线性代码。否,传递给函数的参数和方式不会影响
    wait
    的工作方式,在我的例子中是这只是一个示例,您可以以线性方式更改异步函数中的值,而无需回调和嵌套函数。谢谢@tarkh,最后一个问题,在我的代码上下文中,我理解我需要更改
    getPreset()
    以返回承诺并在
    (async()=>{await getPreset()中等待该承诺);let utpFeature=wait this.featureService.getFeatures(“运行计划”);…})(
    是这样吗?我认为
    Observable
    有一个方法是
    toPromise()
    ,也许我应该用它来代替
    订阅forkjoin
    ,但我会试试,你有什么建议吗?不能说angular,还没有用过它…但在JS中,请记住,
    await
    只在
    async
    函数中工作,并且只在它们内部工作。
    async
    函数之外的所有东西都将运行k因此,按照您需要的方式设计您的软件……您可以,即,将
    promise
    async
    函数本身返回给其父函数,并等待它在那里完成,依此类推