2017-04-22 108 views
0

我想我的函數執行,直到nextPageToken爲null。當我第一次執行這個函數時,它會等待這個承諾被解決。然而,只要響應中存在nextPageToken,函數就不會等待響應併發生堆棧溢出。異步/等待,如何強制我的函數等待,直到承諾解決之後才能繼續?

看起來,f()沒有掛在等待p.then()被調用時。

我完全誤解異步/等待如何工作?

任何幫助將不勝感激......

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

如果你的函數需要「等待」一些異步調用,那麼它也必須是異步。您的功能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) 
); 
+0

我試圖使'apiResult2()'異步功能,移動'f()'中的returnArray並返回它,然後添加'return await f();'但是,結果仍然是一樣的。 這裏是我從哪裏調用apiResult2,如果有幫助? 'ngOnInit(){ this.sub = this.route.params.subscribe(params => { this.students = this.googleApi.apiResult2('https://classroom.googleapis.com/v1/courses/' + params ['id'] +'/ students','students'); }); }' –

+0

嘿阿德里安,檢查我的編輯。 –

+0

非常感謝!該函數現在等待第一個Api調用完成,然後再請求下一個。 當我使用新功能時,會發生兩件意想不到的事情。 1.每次該功能很有趣時,同一個API調用中的兩個一起調度。 2.當我console.log返回值,結果是承諾,而不是數組?? )'在前面的函數中,返回是一個數組...任何想法? –