Javascript Node.js中的同步请求
如何使Node.js中的“request”模块以同步方式加载内容?我所看到的最好的建议是以某种方式使用回调函数,使函数在完成之前不返回自身。我试图在代码中内联使用“request”函数(需要根据不能放在回调中的数据进行处理) 那么,我如何使用'request'模块的回调来阻止它在加载完资源之前返回自身呢 我所做的是运行一个循环,从API下载两个值,然后根据这些值进行一些计算。虽然计算可以在回调中完成。。。循环将在没有执行下一个操作所需的值的情况下前进。(因此,在数据准备就绪之前停止循环将解决问题)Javascript Node.js中的同步请求,javascript,node.js,Javascript,Node.js,如何使Node.js中的“request”模块以同步方式加载内容?我所看到的最好的建议是以某种方式使用回调函数,使函数在完成之前不返回自身。我试图在代码中内联使用“request”函数(需要根据不能放在回调中的数据进行处理) 那么,我如何使用'request'模块的回调来阻止它在加载完资源之前返回自身呢 我所做的是运行一个循环,从API下载两个值,然后根据这些值进行一些计算。虽然计算可以在回调中完成。。。循环将在没有执行下一个操作所需的值的情况下前进。(因此,在数据准备就绪之前停止循环将解决问题
简单的回答是:不要。如果您想要线性读取的代码,请使用像seq这样的库。但不要期望同步。你真的不能。这是件好事 几乎没有什么东西不能放入回调中。如果它们依赖于公共变量,则创建一个闭包来包含它们。手头的实际任务是什么 您希望有一个计数器,并且只在数据存在时调用回调:
var waiting = 2;
request( {url: base + u_ext}, function( err, res, body ) {
var split1 = body.split("\n");
var split2 = split1[1].split(", ");
ucomp = split2[1];
if(--waiting == 0) callback();
});
request( {url: base + v_ext}, function( err, res, body ) {
var split1 = body.split("\n");
var split2 = split1[1].split(", ");
vcomp = split2[1];
if(--waiting == 0) callback();
});
function callback() {
// do math here.
}
2018年更新:node.js在最新版本中支持async/await关键字,并且通过将异步流程表示为承诺的库,您可以等待它们。您可以通过程序获得线性、连续的流程,其他工作可以在您等待的过程中进行。它构建得非常好,值得一试。您应该看看名为
并尝试使用async.series调用解决您的问题。Aredridels的答案相对较好(对它进行了投票),但我认为它缺少等效的循环。这将有助于您: 同步代码等效项:
while (condition) {
var data = request(url);
<math here>
}
return result;
while(条件){
var数据=请求(url);
}
返回结果;
用于串行执行的异步代码:
function continueLoop() {
if (!condition) return cb(result);
request(url, function(err, res, body) {
<math here>
continueLoop()
})
}
continueLoop()
函数continueLoop(){
如果(!条件)返回cb(结果);
请求(url、函数(err、res、body){
continueLoop()
})
}
continueLoop()
虽然node.js的本质可能是异步样式,通常不应该这样做,但有时您希望这样做
我正在编写一个方便的脚本来检查一个API,并且不想因为回调而把它搞砸
Javascript不能执行同步请求,但C库可以
简单的回答是:不要。(…)你真的不能。这是件好事 我想澄清这一点: NodeJS不支持。它的设计并不是为了支持他们开箱即用,但是如果你足够热衷,这里有一些变通方法,下面是一个例子:
var request = require('sync-request'),
res1, res2, ucomp, vcomp;
try {
res1 = request('GET', base + u_ext);
res2 = request('GET', base + v_ext);
ucomp = res1.split('\n')[1].split(', ')[1];
vcomp = res2.split('\n')[1].split(', ')[1];
doSomething(ucomp, vcomp);
} catch (e) {}
当您打开“同步请求”库上的引擎盖时,您可以看到它在后台运行同步。正如sync请求中所解释的,应该非常谨慎地使用它。这种方法锁定主线程,这对性能不利
但是,在某些情况下,编写异步解决方案几乎没有或根本没有好处(与编写更难阅读的代码所造成的某些伤害相比)
这是其他语言(Python、Java、C#等)中许多HTTP请求库的默认假设,这一理念也可以应用到JavaScript中。语言毕竟是解决问题的工具,如果利大于弊,有时您可能不想使用回调
对于JavaScript纯粹主义者来说,这可能是异端邪说,但我是一个实用主义者,因此我可以清楚地看到,如果您发现自己处于以下某些场景中,使用同步请求的简单性会有所帮助:
请注意,上述代码不应用于生产。如果你要运行一个合适的API,那么就使用回调、承诺、异步/等待等等,但除非你想为服务器上浪费的CPU时间付出巨大代价,否则就不要使用同步代码。2018年,你可以在Node.js中使用
async
和wait
来编程“常规”风格
下面是一个示例,它将请求回调包装在承诺中,然后使用await
获取解析值
const request = require('request');
// wrap a request in an promise
function downloadPage(url) {
return new Promise((resolve, reject) => {
request(url, (error, response, body) => {
if (error) reject(error);
if (response.statusCode != 200) {
reject('Invalid status code <' + response.statusCode + '>');
}
resolve(body);
});
});
}
// now to program the "usual" way
// all you need to do is use async functions and await
// for functions returning promises
async function myBackEndLogic() {
try {
const html = await downloadPage('https://microsoft.com')
console.log('SHOULD WORK:');
console.log(html);
// try downloading an invalid url
await downloadPage('http:// .com')
} catch (error) {
console.error('ERROR:');
console.error(error);
}
}
// run your async function
myBackEndLogic();
const request=require('request');
//用承诺包装一个请求
函数下载页(url){
返回新承诺((解决、拒绝)=>{
请求(url,(错误、响应、正文)=>{
如果(错误)拒绝(错误);
如果(response.statusCode!=200){
拒绝(“无效状态代码”);
}
决议(机构);
});
});
}
//现在以“常规”方式编程
//您只需使用异步函数并等待
//对于返回承诺的函数
异步函数myBackEndLogic(){
试一试{
const html=wait downloadPage('https://microsoft.com')
log('SHOULD WORK:');
log(html);
//尝试下载无效的url
等待下载页面('http://.com')
}捕获(错误){
console.error('error:');
控制台错误(error);
}
}
//运行异步函数
myBackEndLogic();
您可以对请求库执行完全类似的操作,但这是使用consthttps=require('https')进行同步的代码>或consthttp=require('http')代码>,应随节点一起提供
举个例子,
consthttps=require('https');
常量http_get1={
主持人:“www.googleapis.com”,
端口:'443',
路径:'/youtube/v3/search?arg=1',
方法:“GET”,
标题:{
“内容类型”:“应用程序/json”
}
};
常数http\u ge
const request = require('request');
// wrap a request in an promise
function downloadPage(url) {
return new Promise((resolve, reject) => {
request(url, (error, response, body) => {
if (error) reject(error);
if (response.statusCode != 200) {
reject('Invalid status code <' + response.statusCode + '>');
}
resolve(body);
});
});
}
// now to program the "usual" way
// all you need to do is use async functions and await
// for functions returning promises
async function myBackEndLogic() {
try {
const html = await downloadPage('https://microsoft.com')
console.log('SHOULD WORK:');
console.log(html);
// try downloading an invalid url
await downloadPage('http:// .com')
} catch (error) {
console.error('ERROR:');
console.error(error);
}
}
// run your async function
myBackEndLogic();
var request = require('sync-request');
var res = request('GET', 'http://example.com');
console.log(res.getBody());