应用程序向服务器发出API请求并返回收到的响应。这里想了解
(i)是否正确地进行API调用并从服务器接收响应。
(ii)如果返回语句的返回语句是正确的
该模块被称为
str = apiRequest(search, lang);
模块是
var https = require('https');
function apiRequest(search, lang) {
var options = {
host: 'localhost:8080',
path: '/api?search=' + search + '&lang=' + lang
};
function resData(res) {
console.log("Status Code : ", res.statusCode);
var str = '';
res.on('data', function (chunk) {
str += chunk;
});
res.on('end', function () {
return JSON.parse(str); // Is this a right way to return data
});
res.on('error', function(e) {
console.error(e);
});
}
https.get(options, resData).end();
};
答案 0 :(得分:1)
不,这不起作用。我将对以下相关部分发表评论。
而不是apiRequest
:
function apiRequest(search, lang) {
function resData(res) {
// ...
res.on('end', function () {
return JSON.parse(str); // Is this a right way to return data
});
// ...
}
https.get(options, resData).end();
}
并用:
调用它str = apiRequest(search, lang);
您应该通过回调或返回承诺。
您的apiRequest
函数可以采取额外的参数,即回调:
function apiRequest(search, lang, callback) {
function resData(res) {
// ...
res.on('end', function () {
callback(null, JSON.parse(str));
});
res.on('error', function(e) {
console.error(e);
callback(e);
});
// ...
}
https.get(options, resData).end();
}
现在您可以将其用作:
apiRequest(search, lang, function (error, str) {
if (err) {
// you have error
} else {
// you have your str here
}
});
您的apiRequest
函数可以返回一个承诺:
function apiRequest(search, lang, callback) {
return new Promise(function (resolve, reject) {
function resData(res) {
// ...
res.on('end', function () {
resolve(JSON.parse(str));
});
res.on('error', function(e) {
console.error(e);
reject(e);
});
// ...
}
https.get(options, resData).end();
}
}
现在您可以将其用作:
apiRequest(search, lang)
.then(function (str) {
// you have your str here
})
.catch(function (err) {
// you have error
});
这未经过测试,因此可能存在一些小错误,但这是一般性的想法。当我发现一些错误时,我会更新答案。
总而言之,您可以使用两种样式来组合这样的异步函数:回调或承诺。您将无法仅返回数据,因为return
基本上是同步的 - 您必须立即返回 - 除非您返回的是可以在以后解决或拒绝的承诺。
还应记住,您应始终在JSON.parse()
内运行try {} catch {} block
来处理错误的JSON错误,否则整个应用程序可能会崩溃。 JSON.parse()
会在输入错误时抛出异常。有关详细信息,请参阅this answer。
这会使您的代码更加复杂,但您可以使用request
模块避免这种复杂化并使其更简单 - 请参阅下面的更新。
要有一个更简单的工作示例,并且您不必手动解析JSON,请考虑我刚刚编写的代码,基于您的示例,但调用GitHub API,以便每个人都可以测试它 - 它给出他的GitHub昵称打印某人的网站,但其他方式与你的代码类似:
'use strict';
var request = require('request');
function apiRequest(search, callback) {
var options = {
url: 'https://api.github.com/users/' + search,
json: true,
headers: {'User-Agent': 'request'}
};
function resData(err, res, data) {
if (err) {
callback(err);
} else if (res.statusCode !== 200) {
callback(res.statusCode);
} else {
// data is already parsed as JSON:
callback(null, data.blog);
}
}
request.get(options, resData);
}
apiRequest('rsp', function (err, data) {
if (err) {
console.log('Error:', err);
} else {
console.log('Data:', data);
}
});
这是使用回调的示例。
以下是使用promises的示例:
'use strict';
var request = require('request');
function apiRequest(search, callback) {
return new Promise(function (resolve, reject) {
var options = {
url: 'https://api.github.com/users/' + search,
json: true,
headers: {'User-Agent': 'request'}
};
function resData(err, res, data) {
if (err) {
reject(err);
} else if (res.statusCode !== 200) {
reject(res.statusCode);
} else {
// data is already parsed as JSON:
resolve(data.blog);
}
}
request.get(options, resData);
});
}
apiRequest('rsp')
.then(function (data) {
console.log('Data:', data);
})
.catch(function (err) {
console.log('Error:', err);
});
使用胖箭头函数和匿名函数以及对象文字可以进一步简化它:
'use strict';
var request = require('request');
function apiRequest(search, callback) {
return new Promise((resolve, reject) => {
request.get({
url: 'https://api.github.com/users/' + search,
json: true,
headers: {'User-Agent': 'request'}
}, (err, res, data) => {
if (err) {
reject(err);
} else if (res.statusCode !== 200) {
reject(res.statusCode);
} else {
resolve(data.blog);
}
});
});
}
apiRequest('rsp')
.then(data => console.log('Data:', data))
.catch(err => console.log('Error:', err));
您可以看到其他一些答案,其中我解释了回调和承诺之间的区别以及如何更详细地使用它们,您可能会觉得有用: