2017-04-22 106 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返回值,结果是承诺,而不是数组?? )'在前面的函数中,返回是一个数组...任何想法? –