JSON.parse 将空数组添加到字符串参数的末尾

3

我正在编写一个简单的Node.JS应用程序,用于与GitHub API配合使用以拉取用户统计信息。 我向/repos/:user/:repo_name/stats/contributors 发送了一个GET请求,这个请求应该会返回一个JSON字符串。以下是我的函数:

function getRepoCommits(token,repos,user,callback) {
    for (var i=0; i<repos.length; i++) {
        var returnChunk = '';
        var full_name = repos[i].full_name;
        //console.log(full_name);
        var options = {
            host: 'api.github.com',
            path: '/repos/'+full_name+'/stats/contributors',
            method: 'GET',
            headers: {
                'Accept': 'application/json',
                'Authorization': 'token '+token,
                'Content-Type': 'application/x-www-form-urlencoded',
            }
        };

        var request = https.request(options, function(res) {
            //res.setEncoding('utf8');
            res.on('data', function(chunk) {
                returnChunk += chunk;
            });
            res.on('end', function(chunk) {
                console.log(returnChunk);
                var stats = JSON.parse(returnChunk);
                console.log(stats.length);
                for (var j=0;j<stats.length;j++) {
                }
                if (i == repos.length-1) {
                    //callback();
                }
            })
        });

        request.on('error',function(err) {
            callback(err);
            console.log(err);
        });
        request.end();
    }
}

感兴趣的领域就在这里:

            res.on('end', function(chunk) {
                console.log(returnChunk);
                var stats = JSON.parse(returnChunk);
                console.log(stats.length);
                for (var j=0;j<stats.length;j++) {
                }
                if (i == repos.length-1) {
                    //callback();
                }
            })

当我检查returnChunk的值时,它是一个符合以下格式的有效JSON字符串:
[{json}]

然而,当函数到达JSON.parse时,它会抛出以下错误:

SyntaxError: Unexpected token [

基本上,在解析字符串之前,它会在末尾添加额外的[],变成:
[{json}][]

我已经连续几个小时尝试解决这个问题,但是似乎找不到原因。你有什么想法吗?


它是将 [] 添加到末尾的意思是什么?你在日志中看到了吗? - Blue Skies
2
我明白发生了什么。您正在循环中进行多个异步请求,并让它们都附加到相同的“returnChunk”变量,因此所有数据都混在一起。请记住,JavaScript没有块作用域,只有函数作用域,因此就好像您在函数顶部放置了“var returnChunk =”“”。 - Blue Skies
1
@BlueSkies - 你应该把那个作为答案发布... - Alexei Levenkov
1个回答

4
你正在循环中进行多个异步请求,将它们都附加到同一个returnChunk变量中,因此所有数据都混合在一起。
请记住,JavaScript没有块级作用域,只有函数级作用域,就好像你在函数顶部放置了var returnChunk = ""一样。
解决方案是使用.forEach()代替for语句,这样回调函数会为每个迭代提供一个新的作用域。
repos.forEach(function(repo, i) {
    var returnChunk = '';
    var full_name = repo.full_name;
    //console.log(full_name);
    var options = {
        host: 'api.github.com',
        path: '/repos/'+full_name+'/stats/contributors',
        method: 'GET',
        headers: {
            'Accept': 'application/json',
            'Authorization': 'token '+token,
            'Content-Type': 'application/x-www-form-urlencoded',
        }
    };

    var request = https.request(options, function(res) {
        //res.setEncoding('utf8');
        res.on('data', function(chunk) {
            returnChunk += chunk;
        });
        res.on('end', function(chunk) {
            console.log(returnChunk);
            var stats = JSON.parse(returnChunk);
            console.log(stats.length);
            for (var j=0;j<stats.length;j++) {
            }

// !!! This will be unreliable because you don't know which one will finish last.
//     You could maintain a separate counter that is incremented as each "end" fires
//        to make sure the `callback()` happens on the last one.
            if (i == repos.length-1) {
                //callback();
            }
        })
    });

    request.on('error',function(err) {
        callback(err);
        console.log(err);
    });
    request.end();
});

太谢谢你了!它完美地运行了。这真是一个让人啼笑皆非的时刻,从中我看到了自己还有很多需要学习的地方!我想给你点赞,可惜我目前还没有足够的声望值! - thecalvinchan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接