尝试获取 promise nodejs 时没有解决任何问题

nothing resolve when try to fetch in promise 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) 
}

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

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

聚会迟到了,很高兴有一个例外的答案,但我会通过稍微重组来修复 OP 代码。看起来 fetch() 函数回答了一个承诺,所以没有必要创建一个承诺。接下来,我将获取和递归调用拆分为单独的方法。首先...

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

我认为这行得通,它的好处是下一个 reader 可以 看到它行得通 并且可以 看到它行得通的原因.