【问题标题】:Waiting for asynchronous functions in Angular 6在 Angular 6 中等待异步函数
【发布时间】:2018-10-30 18:44:36
【问题描述】:

我需要一些关于我的 Angular 6 项目的建议和最佳实践技巧。

您可以在下面看到一些伪代码(请忽略任何拼写错误),但这基本上就是正在发生的事情。该项目通过几个步骤来获取新的和新鲜的数据并在向用户展示之前对其进行处理。 我想要做的是让它通过所有步骤 1 直到它完成,然后进入步骤 2,一旦完成它就进入步骤 3,依此类推。 这是因为某些步骤需要上一步的响应才能提出请求,这意味着我需要等待每个步骤完成,然后再继续下一步。 但是我对异步函数有一点问题。

var token;

mainFunction(){
    step1();
    console.log("Done with step 1");

    step2();
    console.log("Done with step 2");

    step3();
    console.log("Done with step 3");
}

step1(){
    console.log("Step 1...");
    var data1 = getData();
    // Does things with data1
}

step2(){
    console.log("Step 2...");
    var data2 = getData();
    // Does things with data2
}

step3() {
    console.log("Step 3...");
    var data3 = getData();
    // Does things with data3
}

async getData(){
    await getAccessToken();

    var result;

    console.log("Getting data...");

    // Makes a request to an API.
    this.http.post("URL", token)
    .map(response => response.json())
    .toPromise()
    .then((response: any) => {
        console.log("Got the data!");

        // Processing the response
        result = response;
    }
    return result;
}

async getAccessToken(){
    console.log("Getting access token...");

    let accessToken = await getToken(); //Returns a Promise

    this.token = accessToken;
    console.log("Got the token!");

    return Promise.resolve(true);
}

问题始于 getAccessToken 函数中的 getToken()。这是一个返回承诺的异步函数,这意味着它不等待响应。没问题,设置一个 await 就可以了!

但是即使 getAccessToken() 现在等待 getToken() 完成,getData() 也不会等待 getAccessToken() 完成等待 getToken()。解决方案?我返回了一个 Promise 并将 await 放入 getData() 中。 但是我没有解决我只是移动它的问题。

现在 getData() 在执行请求之前等待 accessToken 完成,但 step1、step2 和 step 3 不会等待。 解决方案是一直返回承诺并在每个函数上设置等待吗?我希望有一种更简洁的方法来做到这一点,只需将 await 设置在它实际需要等待的地方,一切都会停止并等待它完成。

有没有一种干净的方法可以做到这一点?什么是最佳做法?

这是我想要的输出:

  • 第 1 步...
  • 正在获取访问令牌...
  • 得到令牌!
  • 正在获取数据...
  • 得到数据!
  • 步骤 1 完成
  • 第 2 步...
  • 正在获取访问令牌...
  • 得到令牌!
  • 正在获取数据...
  • 得到数据!
  • 第 2 步完成
  • 第三步...
  • 正在获取访问令牌...
  • 得到令牌!
  • 正在获取数据...
  • 得到数据!
  • 完成第 3 步

这是我得到的输出:

  • 第 1 步...
  • 正在获取访问令牌...
  • 步骤 1 完成
  • 第 2 步...
  • 正在获取访问令牌...
  • 第 2 步完成
  • 第三步...
  • 正在获取访问令牌...
  • 完成第 3 步
  • 得到令牌!
  • 正在获取数据...
  • 得到数据!
  • 得到令牌!
  • 正在获取数据...
  • 得到数据!
  • 得到令牌!
  • 正在获取数据...
  • 得到数据!

【问题讨论】:

    标签: javascript typescript asynchronous async-await angular6


    【解决方案1】:

    解决方案是一路返回promise并在每个函数上设置await吗?

    是的(但请注意,您不需要像getAccessToken 中那样明确这样做,更多内容见下文)。如果函数依赖于异步函数的结果,那么该函数也必须是异步的。这会一直冒泡。

    如果您希望mainFunction 按顺序处理step1step2step3,并且它们依赖于异步结果,那么它们必须是异步的,而mainFunction 必须是异步的(以及任何使用它必须是异步的):

    async function mainFunction() {
        console.log("mainFunction start");
        await step1();
        console.log("step1 done");
        await step2();
        console.log("step2 done");
        await step3();
        console.log("step3 done");
        console.log("mainFunction done");
    }
    async function step1() {
        await getData();
    }
    async function step2() {
        await getData();
    }
    async function step3() {
        await getData();
    }
    async function getData() {
        await getAccessToken();
        return Math.floor(Math.random() * 1000);
    }
    async function getAccessToken() {
        await asyncStandIn();
    }
    function asyncStandIn() {
        return new Promise(resolve => setTimeout(resolve, 800));
    }
    
    // Top level entry
    (async () => {
        mainFunction();
    })().catch(error => {
        console.error(error);
    });

    回复getAccessToken:只需将其设为async 函数,就意味着它总是返回一个承诺。不需要return Promise.resolve(true);,您可以删除该行。 (不过,一个名为 getAccessToken 的函数没有返回 [the promise of] 访问令牌,这有点奇怪。)

    更多阅读;我的看法是,投票结束您的问题作为以下内容的副本是不正确的,但其他人可能会有所不同:

    【讨论】:

    • 谢谢!是的,当我在这里搜索时,我只看到一级函数调用(如果是这种情况,那么 async 和 await 就可以了)但是在这里我有 3 级函数调用,以异步函数结束。但这清除了一切,谢谢!
    • @JohanC。 - 是的。这意味着如果中间函数需要等待向下的那个,它们也必须是异步的,一直向上。
    猜你喜欢
    • 2019-05-17
    • 2023-03-13
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多