【问题标题】:Async / Await, how do I force my function to wait until promise is resolved before it continues?异步/等待,我如何强制我的函数等到承诺解决后再继续?
【发布时间】:2017-09-19 08:34:45
【问题描述】:

我希望我的函数一直执行到 nextPageToken 为空。当我第一次执行该函数时,它会等待 promise 被解决。但是,一旦响应中出现 nextPageToken,该函数就不会等待响应并发生堆栈溢出。

似乎 f() 在调用 await p.then() 时没有挂起。

我完全误解了 async/await 的工作原理吗?

任何帮助将不胜感激...

public apiResult2(path: string, objectName: string, params: any = { }) {
    let returnArray = [];
    const p = new Promise<any> ((resolve, reject) => {
      gapi.load('auth2:client', () => {
        gapi.client.request({
          path: path,
          params: params
        }).then(response => {
          // resolve this promise with the first key in the response object.
          resolve(response.result);
        }, reason => {
          console.log(reason);
          reject(reason.result);
        });
      });
    });
    let f = async () => {
      let nextPageToken = null;
      do {
        let r = await p.then(result => {
          if (result.hasOwnProperty(objectName)) {
            for (let obj of result[objectName]) {
              returnArray.push(obj);
            }
          }
          if (result.hasOwnProperty('nextPageToken')) {
            params.nextPageToken = result.nextPageToken;
            return result.nextPageToken;
            // nextPageToken = result.nextPageToken;
          } else {
            params.nextPageToken = null;
            return null;
            // nextPageToken = null;
          }
        });
        nextPageToken = r;
        console.log(r);
      } while (nextPageToken);
    };
    f();
    return returnArray;
  }

【问题讨论】:

    标签: javascript typescript asynchronous async-await


    【解决方案1】:

    如果您的函数需要“等待”某个异步调用,那么它也必须是异步的。您的函数apiResult2 不会等待f 完成,而是为了return returnArray

    编辑:

    这里的主要问题是您试图重用承诺 p 来发出不同的请求,但这是不可能的。承诺p 将使用第一个请求的参数进行初始化,并且所有对p.then 的调用都将得到相同的结果:第一个页面请求的响应。

    我对您的代码做了一些小改动,并使其与模拟界面一起工作:

    const apiResult2 = async (path: string, objectName: string, params: any = { }) => {
        const requestPage = async () => new Promise<any> ((resolve, reject) => {
            gapi.load('auth2:client', () => {
                gapi.client.request({
                    path: path,
                    params: params
                }).then(response => {
                    // resolve this promise with the first key in the response object.
                    resolve(response.result);
                }, reason => {
                    console.log(reason);
                    reject(reason.result);
                });
            });
        });
    
        let returnArray: string[] = [];
        do {
            const page = await requestPage();
    
            if (page.hasOwnProperty(objectName)) {
                for (let obj of page[objectName]) {
                    returnArray.push(obj);
                }
            }
    
            if (page.hasOwnProperty('nextPageToken')) {
                params.nextPageToken = page.nextPageToken;
            } else {
                params.nextPageToken = null;
            }
        } while (params.nextPageToken);
    
        return returnArray;
    }
    

    使用示例:

    apiResult2(path, objectName, params).then(
        result => console.log(result),
        err => console.log('error', err)
    );
    

    【讨论】:

    • 我尝试将apiResult2() 设为异步函数,将returnArray 移动到f() 中并返回它,然后添加return await f();,但结果仍然相同。这是我调用 apiResult2 的地方,如果有帮助? ngOnInit() { this.sub = this.route.params.subscribe(params =&gt; { this.students = this.googleApi.apiResult2('https://classroom.googleapis.com/v1/courses/' + params['id'] + '/students', 'students'); }); }
    • 非常感谢!!!该函数现在等待第一个 Api 调用完成,然后再请求下一个。当我使用新功能时,发生了两件意想不到的事情。 1.每次函数好玩时,2个相同的api调用一起调度。 2.当我console.log返回值时,结果是promise而不是Array?:(ZoneAwarePromise {__zone_symbol__state: null, __zone_symbol__value: Array(0)}__zone_symbol__state: true__zone_symbol__value: Array(43)__proto__: Object )在前面的函数中return是一个Array...有什么想法吗?
    • 啊,无视上面的评论。查看用法示例,我可以看到我需要在调用函数中解析promise!按预期工作!谢谢!!!
    猜你喜欢
    • 2018-10-02
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 2021-05-21
    • 2021-11-09
    • 2021-02-02
    • 2018-02-03
    • 2018-04-17
    相关资源
    最近更新 更多