[英]Recursive awaited promise does nothing after resolving
我正在向 Twitter API 發出一些請求,為了檢索推文,我需要執行一些遞歸方法調用,因為每個請求最多只能返回 100 條推文。
所以這個過程非常簡單。
next_token
,則緩存結果並使用下一個令牌執行另一個 http 請求。next_token
未定義,此時使用所有推文列表解析 promise。然而這並沒有按預期工作,遞歸 http 工作,但是當遞歸 function 的 else 塊滿足並且 promise 得到解決時,什么也沒有發生。 執行不會 go 回到第一個 function。 一切似乎都在旋轉,什么也不做。 我在每一行都添加了斷點,但沒有任何東西會觸發斷點。
我在哪里錯了?
public async getTweetList(ticker: string): Promise<string[]>{
let tweets: string[] = [];
tweets = await this.getAllTweetsRecursively(ticker, null, tweets);
return tweets;
}
public async getAllTweetsRecursively(ticker: string, nextToken: string, tweetList: string[]): Promise<string[]>{
return new Promise(async (resolve, reject) => {
let query = `?query=(${ticker})`
query += this.extraQuery;
if(nextToken){
query += this.nextTokenQuery + nextToken
}
let res = await axios.default.get(this.url + query, {
headers: this.headers
})
let newNextToken = res.data.meta.next_token;
if(res.data.data.length > 0 && newNextToken){
res.data.data.forEach(tweet => {
tweetList.push(tweet.text);
})
this.getAllTweetsRecursively(ticker, newNextToken, tweetList);
}
else {
resolve(cleanedTweets)
}
})
}
替代實施 - 同樣的問題
public async getTweetList(ticker: string): Promise<string[]>{
return new Promise(async (resolve) => {
let tweets: string[] = [];
tweets = await this.getAllTweetsRecursively(ticker, null, tweets);
resolve(tweets);
})
}
public async getAllTweetsRecursively(ticker: string, nextToken: string, tweetList: string[]): Promise<string[]>{
return new Promise(async (resolve, reject) => {
let query = `?query=(${ticker})`
query += this.extraQuery;
if(nextToken){
query += this.nextTokenQuery + nextToken
}
let res = await axios.default.get(this.url + query, {
headers: this.headers
})
let newNextToken = res.data.meta.next_token;
if(res.data.data.length > 0 && newNextToken){
res.data.data.forEach(tweet => {
tweetList.push(tweet.text);
})
await this.getAllTweetsRecursively(ticker, newNextToken, tweetList);
}
else {
let cleanedTweets: string[] = [];
tweetList.forEach(tweet => {
if(tweet.startsWith("RT")){
return;
}
if(!tweet.toLowerCase().includes("$" + ticker)){
return;
}
cleanedTweets.push(tweet);
});
resolve(cleanedTweets)
}
})
}
問題是內部 promise 在遞歸調用自身的情況下沒有解決。
添加resolve(await this.getAllTweetsRecursively(ticker, newNextToken, tweetList));
解決了這個問題。
public async getTweetList(ticker: string): Promise<string[]> {
let tweets: string[] = [];
return await this.getAllTweetsRecursively(ticker, null, tweets);
}
public async getAllTweetsRecursively(ticker: string, nextToken: string, tweetList: string[]): Promise<string[]>{
return new Promise(async (resolve, reject) => {
let query = `?query=(${ticker})`
query += this.extraQuery;
if(nextToken){
query += this.nextTokenQuery + nextToken
}
let res = await axios.default.get(this.url + query, {
headers: this.headers
})
let newNextToken = res.data.meta.next_token;
if(res.data.data.length > 0 && newNextToken){
res.data.data.forEach(tweet => {
tweetList.push(tweet.text);
})
resolve(await this.getAllTweetsRecursively(ticker, newNextToken, tweetList));
}
else {
res.data.data.forEach(tweet => {
tweetList.push(tweet.text);
})
let cleanedTweets: string[] = [];
tweetList.forEach(tweet => {
if(tweet.startsWith("RT")){
return;
}
if(!tweet.toLowerCase().includes("$" + ticker)){
return;
}
cleanedTweets.push(tweet);
});
resolve(cleanedTweets)
}
})
}
請記住async function() {}
已經定義了一個返回 Promise的函數,因為這就是async
關鍵字為您所做的。 它通過將 function 主體包裝在 Promise 中來使您的主體異步,而無需您自己編寫 promise 代碼。 然后為方便起見, await
關鍵字相當於Promise.then(),無需自己編寫提取代碼。
因此,以下兩個功能是相同的:
function() {
return new Promise(resolve, reject => {
resolve(4);
});
}
async function() {
return 4;
}
兩者都返回 Promise,兩者都可以在另一個async
function 中await
,並且兩者都可以用 .then .then()
鏈接,因為它們實際上是同一件事。 所以對於你的代碼,如果你想使用async
/ await
你不應該也構建 Promises:
public async getTweetList(ticker: string): Promise<string[]> {
return await this.getAllTweetsRecursively(ticker, null, []);
}
public async getAllTweetsRecursively(ticker: string, nextToken: string, tweetList: string[]): Promise<string[]>{
let query = `?query=(${ticker})${this.extraQuery}`;
if(nextToken){
query = `${query}${this.nextTokenQuery}${nextToken}`;
}
let res = await axios.default.get(this.url + query, {
headers: this.headers
})
let newNextToken = res.data.meta.next_token;
if(res.data.data.length > 0 && newNextToken){
res.data.data.forEach(tweet => tweetList.push(tweet.text))
return await this.getAllTweetsRecursively(ticker, newNextToken, tweetList));
}
// no need for "else": the "if" already returns.
res.data.data.forEach(tweet => tweetList.push(tweet.text))
let cleanedTweets: string[] = [];
tweetList.forEach(tweet => {
if(tweet.startsWith("RT")) return;
if(!tweet.toLowerCase().includes("$" + ticker)) return;
cleanedTweets.push(tweet);
});
return cleanedTweets
})
}
您的代碼包含async getAllTweetsRecursively(...) { return new Promise(async (resolve, reject) => {... }))
現在將返回三個嵌套的承諾,因為這些async
關鍵字使得:
getAllTweetsRecursively(...) {
return new Promise(resolve, reject => {
return new Promise(async (resolve, reject) => {
...
}))
});
}
由於該async
進一步展開為:
getAllTweetsRecursively(...) {
return new Promise(resolve, reject => {
return new Promise((resolve, reject) => {
return new Promise(resolve, reject => {
resolve(...)
})
}))
});
}
這種方式是瘋狂的=)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.