尝试获取promise nodejs时无法解决问题

时间:2017-06-24 17:01:26

标签: javascript node.js promise fetch es6-promise

我使用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具有访问速率限制。

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

2 个答案:

答案 0 :(得分:1)

这种情况下的问题是您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) 
}

您可以通过以下方式更改此设置,然后解决您的回调

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

基本上就是这样:

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

根据建议对线进行更改,流程将为

  • 调用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);
    });
  });
};

答案 1 :(得分:0)

参加晚会,很高兴有一个例外答案,但我通过重新组织来修复OP代码。看起来fetch()函数回答了一个promise,因此不需要创建Promise。接下来,我将获取和递归调用拆分为单独的方法。第一...

// 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
    })
}

这很容易阅读:获取,附加到结果,回答长度。现在创建一个调用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
    })
}

我认为这是有效的,并且它的好处是下一位读者可以看到它正常工作并且可以看到它的工作原理