异步/等待,我如何强制我的功能等到承诺在继续之前解决?

时间:2017-04-22 10:13:26

标签: javascript typescript asynchronous async-await

我希望我的函数执行,直到nextPageToken为null。当我第一次执行该函数时,它等待承诺得到解决。但是,只要响应中存在nextPageToken,该函数就不会等待响应并发生堆栈溢出。

当调用await p.then()时,似乎没有暂停f()。

我完全误解了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;
  }

1 个答案:

答案 0 :(得分: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)
);