异步等待 - 然后根据先前等待的结果进行嵌套

问题描述 投票:0回答:1

考虑以下不可协商的事项:

我必须使用 3 个异步函数,它们在下面,我无法更改它们。

    async asyncCall1({ caseId }: { caseId: string }) {
        const response = await this.apolloClient.query({...})
        return {
          ...response,
          data: caseResponse,
        }; 
    }


    async asyncCall2({ caseIdFromCall1 }: { caseIdFromCall1: string }) {
        const response = await this.apolloClient.query({...})
        return {
          ...response,
          data: caseResponse,
        }; 
    }

    async asyncCall3({ caseIdFromCall3 }: { caseIdFromCall3: string }) {
        const response = await this.apolloClient.query({...})
        return {
          ...response,
          data: caseResponse,
        }; 
    }

我需要发生的是:

  1. 需要将 asyncCall1 响应中的一个字段输入到 asyncCall2 中,然后需要将 asyncCall2 中的一个字段输入作为 asyncCall 3 的输入。本质上,调用必须按顺序发生。

  2. 我需要将 asyncCall1、asyncCall2 和 asyncCall3 添加到列表中,并在处理 asyncCall3 时根据条件返回布尔值。

  3. 处理每个异常的方法? - 在任何调用中遇到错误的每种情况下,也许都会返回某个布尔值。

  4. 如果解决方案能让我摆脱嵌套地狱

    ,我很高兴

这是我的尝试

    const checkAuthorization = (input: string) => {

        let coalate = []

        dependency1.asyncCall1({ caseId: input })
            .then((call1RawResult) => {
              console.log("Inside caseResult: ", call1Result);
              return { data: call1Result.data.caseProperties.caseId1 }; //This is the response from call 1 that I want to pass to call 2
            })
            .then((call1SpecificField) => dependency2.asyncCall2({caseId: call1SpecificField.data})) //This is where I attempt to use value from asyncCall1
            .then((call2RawResult) => {
              const caseId2 = call2RawResult.data.caseProperties.caseId2; 
              coalate.push(caseId2); //Also push to list
              return { data: caseId2 } //Do some operation and pass this on for use in the next call
            })
            .then((call2SpecificField) => dependency3.asyncCall3({caseId: call2SpecificField.data}))
            .then((call3RawResult) => {
              const caseId3 = call3RawResult.data.caseProperties.caseId2; 
              coalate.push(caseId3); //Also push to list
              
              //Finally return true or false if input is found in consolidated coalate list
              return coalate.includes(input);
            }).catch((error) => { //If any issue in any of the above dependency calls - return false.
              console.log(error)
              return false;
            })

     }
  1. 我的问题是我似乎已经达到了界限
    Inside caseResult:
    ,但从未超越过。
  2. 当调用
    checkAuthorization()
    时,我至少需要从catch块内部计算出布尔值,但它只是显示为未定义。
javascript typescript async-await promise
1个回答
0
投票
  • 现在是 2023 年 - 在我看来,使用
    await
    而不是
    .then()
    callback-hell 会导致代码更容易阅读、编写和理解。
    • 顺便说一句,使用
      await
      并不意味着您在进入范围时必须 await
       每个 
      Promise
      :将返回/接收的 
      Promise
       存储在本地然后 
      await
       存储在本地是完全有效的稍后 - 这就是你如何实现某些类型的重要 Promise 逻辑。

我将逐一逐步实现您的每个目标:

    需要
  • asyncCall1
     响应中的一个字段来输入 
    asyncCall2
  • 然后我需要
  • asyncCall2
     中的一个字段作为 
    asyncCall3
     的输入。 > * 本质上,调用必须按顺序发生。
这很简单:

(顺便说一句,

svc: MyService

是那些
object
方法的
asyncCallN
)。

async function run( svc: MyService, input: string ) { const result1 = await svc.asyncCall1( { caseId: input } ); console.log( "result1: %o", result1 ); const caseId1 = result1.data.caseProperties.caseId1; const result2 = await svc.asyncCall2( { caseId: caseId1 } ); console.log( "result2: %o", result2 ); const caseId2 = result2.data.caseProperties.caseId2; const result3 = await svc.asyncCall3( { caseId: caseId2 } ); console.log( "result3: %o", result3 ); const caseId3 = result3.data.caseProperties.caseId2; // <-- Not `caseId3` ? }


我需要从

asyncCall1

asyncCall2
asyncCall3
 添加到列表,并根据处理 
boolean
 时的条件返回 
asyncCall3

再说一遍,简单明了:

(虽然

我觉得应该使用Set<string>

而不是
Array<string> /
String[]
,因为你的代码将执行集合成员资格检查,这对于
O(1)
来说是
Set<T>
(很好)但是
O(n) 
(坏)对于
Array<T>
)。
async function run( svc: MyService, input: string ): Promise<boolean> {

    const caseIdsSet = new Set<string>();

    const result1 = await svc.asyncCall1( { caseId: input } );
    console.log( "result1: %o", result1 );
    const caseId1 = result1.data.caseProperties.caseId1;
    caseIdsSet.add( caseId1 );

    const result2 = await svc.asyncCall2( { caseId: caseId1 } );
    console.log( "result2: %o", result2 );
    const caseId2 = result2.data.caseProperties.caseId2;
    caseIdsSet.add( caseId2 );

    const result3 = await svc.asyncCall3( { caseId: caseId2 } );
    console.log( "result3: %o", result3 );
    const caseId3 = result3.data.caseProperties.caseId2; // <-- Not `caseId3` ?
    caseIdsSet.add( caseId3 );

    return caseIdsSet.has( input );
}



处理每个异常的方法? - 在任何调用中遇到错误的每种情况下,也许都会返回某个布尔值。

仅在您确实需要时捕获异常:
除非

预期所有这些asyncCallN调用在正常程序操作期间都会失败

并且
您的程序需要在错误情况下做某事(例如回滚)到目前为止任何持续的更改,或取消事务等)那么您不需要需要在程序代码中添加低价值的catch语句。
即使您只想记录任何错误(例如 

catch( err ) { console.error(err); }

),您通常仍然不需要任何

catch
块:大多数 JS 环境仍然/可以在异常抛出时记录异常。
throw
声明。您还应该监听
window
'error'
事件以了解未处理的 JS 异常。


如果解决方案能让我摆脱嵌套地狱,我会很高兴

这个答案。

© www.soinside.com 2019 - 2024. All rights reserved.