我正在处理一个获取给定GitHub用户名的存储库信息的应用程序。
GitHub API每个请求限制为100个项目;所以,如果一个给定的账户有110个回购,我需要再次拨打剩余的十个(你可能会看到它的去向)。 基本上,我希望我的代码能够确定给定帐户可以使用多少个repos页面,并根据需要进行一次或多次调用以获取所有数据。
我已经编写了决定是否进行一次或多次通话的代码。在我遇到多个电话的区块中,我遇到了问题。
我在Node.js工作,而Node的GitHub API客户端提供了一些非常方便的方法来实现我想要实现的目标。
github.repos.getForUser({
username: 'nodejs',
per_page: 100
}).then(result => {
if(!result.meta.link) {
// if there's NO link header, it means
// that there are NO pages to traverse.
// that is: it means we've retrieved all
// available repositories.
console.log('no link header');
console.log('we have retrieved all available repositories');
} else {
// if there IS a link header, we need to
// capture the number of the last page; this
// will allow us tp determine how many pages
// we need to traverse in order to capture
// all available repositories
console.log('link header found');
var link = result.meta;
var num_of_pages = github.hasLastPage(link).match(/&page=(\d{1,})/)[1];
console.log(`At a rate of 100 repos per_page, there are ${num_of_pages} pages to traverse`);
var repos = result.data,
hasNextPage = github.hasNextPage(link);
while(hasNextPage !== undefined) {
github.getNextPage(link, function(err, res) {
console.log(repos.length, res.data.length);
repos = repos.concat(res.data);
hasNextPage = github.hasNextPage(res.meta);
console.log(repos.length, res.data.length, hasNextPage);
});
} //end while
} //end else
});
github.hasNextPage(link)
接受链接头(或响应对象)的内容返回一个字符串,可能看起来像这样
https://api.github.com/user/9950313/repos?per_page=100&access_token={MY_TOKEN}&page=2
它基本上会从链接标题中提取此网址,github.getNextPage(link, [optional header], callback)
用于从下一页获取数据,如果有下一页。如果没有,github.hasNextPage()
将返回undefined。
当我在没有while循环的while循环中运行代码时,它可以正常工作。但是当我在while循环中运行它时,程序会挂起。我已经尝试了一些测试来检查while循环是否在触发;它是。相反,由于某种原因,似乎没有在while循环中触发github.getNextPage(link, [optional header], callback)
。我现在已经看了好几个小时了,似乎无法发现问题。
有人可以帮忙吗?
UPDATE 我试着让代码运行以查看发生了什么,过了一段时间后,我得到了这个
<--- Last few GCs --->
[9094:0x4044a30] 111879 ms: Mark-sweep 1402.2 (1490.1) -> 1402.2 (1462.1) MB, 953.1 / 3.3 ms (+ 0.0 ms in 0 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 953 ms) last resort GC in old space requested
[9094:0x4044a30] 112921 ms: Mark-sweep 1402.2 (1462.1) -> 1402.2 (1462.1) MB, 1042.2 / 4.0 ms last resort GC in old space requested
<--- JS stacktrace --->
==== JS stack trace =========================================
Security context: 0x22e243225ee1 <JSObject>
1: new WritableState [_stream_writable.js:~41] [pc=0x2445e09697e8](this=0x299f6bcfe731 <WritableState map = 0x9510adbf1e9>,options=0x299f6bcb8bd9 <Object map = 0x330625c96891>,stream=0x299f6bcb8b01 <TLSSocket map = 0x330625c97079>)
3: Writable [_stream_writable.js:~194] [pc=0x2445e0974360](this=0x299f6bcb8b01 <TLSSocket map = 0x330625c97079>,options=0x299f6bcb8bd9 <Object map = 0x330625c...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node::Abort() [node]
2: 0x121a2cc [node]
3: v8::Utils::ReportOOMFailure(char const*, bool) [node]
4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [node]
5: v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [node]
6: v8::internal::Runtime_AllocateInTargetSpace(int, v8::internal::Object**, v8::internal::Isolate*) [node]
7: 0x2445e078463d
Aborted (core dumped)
这似乎表明循环实际上正在运行,但是它内部的代码不是......可能导致这种情况的原因?
更新
有人指出link
变量在循环中没有更新......我更正了这个以便更新,但它仍然无法正常工作......!似乎getNextPage
的回调中的代码根本没有运行。
while (hasNextPage !== undefined) {
github.getNextPage(link, function(err, res) {
console.log(repos.length, res.data.length);
repos = repos.concat(res.data);
link = res.meta; hasNextPage = github.hasNextPage(res.meta);
console.log(repos.length, res.data.length, hasNextPage, link);
});
} //end while
但是,如果我像这样运行它,它可以正常工作
github.getNextPage(link, function(err, res) {
console.log(repos.length, res.data.length);
repos = repos.concat(res.data);
link = res.meta; hasNextPage = github.hasNextPage(res.meta);
console.log(repos.length, res.data.length, hasNextPage, link);
});