尝试获取承诺nodejs时没有任何解决办法

我使用fetch来触发api代码。

const getData = (workspaceId, start, end, projectId, page, tmpData) => { return new Promise((resolve,reject) => { let result = [] if (tmpData !== null){ result.push(tmpData) } fetch('https://toggl.com/reports/api/v2/details?workspace_id='+workspaceId +'&since='+start+'&until='+end+'&user_agent=api_test&project_ids='+projectId +'&page='+page, { method: 'get', headers: { 'Authorization': 'Basic '+new Buffer(token.api_token+':api_token').toString('base64') } }).then(res=>{ return res.json() }).then(json=>{ if (json.data.length > 0){ result.push(json) console.log('on page '+page) getData(workspaceId, start, end, projectId, page+1, result) } else { console.log('end on page '+page) result.push(json) console.log(result) //this line is log the result successfully resolve(result) // but this not resolve i don't know why } }).catch(err=>{ reject(err) }) }) } 

如果你想获取所有你需要的数据来增加参数(页面)来访问下一个数据,那么toggl api有访问速率的限制。

一次请求中无法获取所有数据。

在这种情况下的问题是你的getData调用第二页。 如果没有数据,你的决心就会奏效,但现在你的问题是你解决了,没有人听。

 if (json.data.length > 0){ result.push(json) console.log('on page '+page) // nobody is listening for the promise to complete // any resolve called later, will be not handled getData(workspaceId, start, end, projectId, page+1, result) } 

你可以用下面的方法改变它,然后解决你的callback

 getData(workspaceId, start, end, projectId, page + 1, result).then(() => resolve(result)) 

所以基本上是这样的:

  • 调用getData(A)
    • 调用getData(B)
    • 调用getData(C)
    • C解决,因为没有更多的数据可用

随着build议的改变,stream量将是

  • 调用getData(A)
    • 调用getData(B)
    • 调用getData(C)
    • C解决,因为没有更多的数据可用
    • B解决
  • A解决

所以你基本上得到3个决议

完整的代码更改将是:

 const getData = (workspaceId, start, end, projectId, page, tmpData) => { return new Promise((resolve,reject) => { let result = []; if (tmpData !== null){ result.push(tmpData); } fetch('https://toggl.com/reports/api/v2/details?workspace_id=' + workspaceId + '&since='+ start + '&until=' + end + '&user_agent=api_test&project_ids=' + projectId +'&page=' + page, { method: 'get', headers: { 'Authorization': 'Basic '+new Buffer(token.api_token+':api_token').toString('base64') } }).then(res=>{ return res.json(); }).then(json=>{ if (json.data.length > 0){ result.push(json); console.log('on page '+page); getData(workspaceId, start, end, projectId, page+1, result) .then(() => resolve(result)) .catch(err => reject(err)); } else { console.log('end on page '+page); result.push(json); console.log(result); resolve(result); } }).catch(err=>{ reject(err); }); }); }; 

晚会之后,很高兴有一个例外的答案,但我会修改操作代码,重新组织一下。 它看起来像fetch()函数答应了一个承诺,所以没有必要创build一个Promise。 接下来,我会将抓取和recursion调用拆分为不同的方法。 第一…

 // do a fetch, appending to result, answer a promise for the length of data fetched const fetchAndAppend = (workspaceId, start, end, projectId, page, result) => { return fetch('https://toggl.com/reports/api/v2/details?workspace_id='+workspaceId +'&since='+start+'&until='+end+'&user_agent=api_test&project_ids='+projectId +'&page='+page, { method: 'get', headers: { 'Authorization': 'Basic '+new Buffer(token.api_token+':api_token').toString('base64') } }).then(res=>{ return res.json() // is this really async? I would have guessed not }).then(json=>{ result.push(json) return json.data.length }) } 

这很容易阅读:获取,附加到结果,回答长度。 现在做一个recursion方法,调用fetch …

 // keep fetching until no data is returned, answer a promise for the complete data const getData = (workspaceId, start, end, projectId, page, tmpData, result) => { result = result || [] return fetchAndAppend(workspaceId, start, end, projectId, page, result) .then(length => { return (length)? getData(workspaceId, start, end, projectId, page+1, tmpData, result) : result }) } 

我认为这是有效的,它的好处是下一个读者可以看到它的工作原理,并可以看到它为什么工作