Kyl*_*iss 39 javascript node.js
我如何使Node.js中的'request'模块以同步方式加载?我看到的最好的建议是以某种方式使用回调来使函数在完成之前不返回自身.我试图在代码中内联使用'request'函数(需要根据无法放在回调中的数据处理事物).
那么我怎么能使用'request'模块的回调来阻止它自己返回,直到它完成加载资源?
我正在做的是运行一个从API下载两个值的循环,然后根据这些值进行一些数学运算.虽然数学可以在回调中完成......循环将在没有执行下一个操作所需的值的情况下前进.(因此,阻止循环前进直到数据准备就绪可以解决问题)
/* loop */ {
/* URL Generation */
request( {url: base + u_ext}, function( err, res, body ) {
var split1 = body.split("\n");
var split2 = split1[1].split(", ");
ucomp = split2[1];
});
request( {url: base + v_ext}, function( err, res, body ) {
var split1 = body.split("\n");
var split2 = split1[1].split(", ");
vcomp = split2[1];
});
/* math which needs to be after functions get variables and before loop advances */
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*las 51
简短的回答是:不要.(...)你真的不能.这是一件好事
我想直截了当地记录下来:
的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) {}
Run Code Online (Sandbox Code Playgroud)
当您在'sync-request'库中打开引擎盖时,您可以看到它在后台运行同步子进程.正如在sync-request README中所解释的那样,它应该非常明智地使用.这种方法锁定主线程,这对性能不利.
但是,在某些情况下,通过编写异步解决方案几乎没有或没有优势(与通过编写难以阅读的代码所做的某些伤害相比).
这是许多其他语言(Python,Java,C#等)中的HTTP请求库所持有的默认假设,并且该哲学也可以传递给JavaScript.语言毕竟是解决问题的工具,有时候如果好处大于缺点,你可能不想使用回调.
对于JavaScript纯粹主义者来说,这可能是异端邪说,但我是一个实用主义者,所以我可以清楚地看到,如果您发现自己处于以下某些情况中,使用同步请求的简单性会有所帮助:
测试自动化(测试通常是同步的).
快速API混搭(即黑客马拉松,概念验证等).
帮助初学者(之前和之后)的简单示例.
请注意,上述代码不应用于生产.如果要运行适当的API然后使用回调,使用异步库,使用promises或其他,但避免同步代码,除非您想在服务器上浪费大量的CPU时间.
Tim*_*imo 35
在2018年,您可以在Node.js中使用async
和await
编写"通常"样式.
下面是一个示例,它在promise中包装请求回调,然后用于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();
Run Code Online (Sandbox Code Playgroud)
are*_*del 10
简短的回答是:不要.如果您想要线性读取的代码,请使用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.
}
Run Code Online (Sandbox Code Playgroud)
更新2018:node.js支持最新版本中的async/await关键字,并且使用表示异步进程作为promise的库,您可以等待它们.通过程序可以获得线性,顺序的流程,等待时可以继续进行其他工作.它构造得非常好,值得一试.
尽管异步风格可能是 node.js 的本质,通常您不应该这样做,但有时您还是想这样做。
我正在编写一个方便的脚本来检查 API 并且不想将它与回调混淆。
Javascript 不能执行同步请求,但 C 库可以。
https://github.com/dhruvbird/http-sync
Aredridels答案相对较好(upvoted it),但我认为它缺少循环等效.这应该可以帮到你:
同步代码等效:
while (condition) {
var data = request(url);
<math here>
}
return result;
Run Code Online (Sandbox Code Playgroud)
串行执行的异步代码:
function continueLoop() {
if (!condition) return cb(result);
request(url, function(err, res, body) {
<math here>
continueLoop()
})
}
continueLoop()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
74894 次 |
最近记录: |