我希望我的函数执行,直到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;
}
答案 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)
);