尝试获取 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 可以 看到它行得通 并且可以 看到它行得通的原因.
我使用 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 可以 看到它行得通 并且可以 看到它行得通的原因.