Node.js中的同步请求

我怎么能让Node.js中的'request'模块以同步的方式加载? 我见过的最好的build议是以某种方式使用callback函数来获取函数,直到完成。 我试图在代码中内联使用'request'函数(事情需要根据那些不能放在callback中的数据来处理)。

那么我怎么才能使用“请求”模块的callback,以防止它自己回来,直到它完成加载资源?

我在做的是运行一个循环,从API下载两个值,然后必须根据这些值做一些math运算。 虽然math可以在callback中完成…循环将提前没有它需要执行下一个操作的值。 (所以停止循环直到数据准备就绪可以解决问题)

/* 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 */ } 

简短的回答是:不。 如果你想要线性读取的代码,可以使用像seq这样的库。 但是不要指望同步。 你真的不能。 这是一件好事。

没有什么东西不能放在callback中。 如果它们依赖于公共variables,则创build一个闭包来包含它们。 什么是手头的实际任务?

你想要一个计数器,只有在数据存在的时候才能调用callback函数:

 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. } 

简短的回答是:不。 (…)你真的不能。 这是一件好事

我想就这个问题写下正确的logging:

NodeJS 确实支持同步请求 。 这不是为了支持它们而devise的,但是如果你足够敏锐的话,有几个解决方法,这里是一个例子:

 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-request'库中打开引擎盖时,可以看到这在后台运行了一个同步subprocess 。 正如同步请求README中所解释的,应该非常明智地使用它。 这种方法locking主线程,这对性能不利。

但是,在某些情况下,通过编写asynchronous解决scheme(与通过编写难以阅读的代码所造成的某些损害相比),获得的好处很less或没有。

这是许多其他语言(Python,Java,C#等)中的HTTP请求库所保存的默认假设,并且该哲学也可以被带到JavaScript中。 语言是解决问题的工具,有时你可能不想使用callback,如果利大于弊。

对于JavaScript纯粹主义者来说,这可能是异端邪说,但我是一个实用主义者,所以我可以清楚地看到,使用同步请求的简单性有助于您发现自己处于以下某些情况:

  1. testing自动化 (testing通常是同步的)。

  2. 快速API混搭 (即黑客马拉松,概念validation工程等)。

  3. 简单的例子来帮助初学者 (之前和之后)。

被警告上面的代码应该用于生产。 如果你打算运行一个合适的API,那么使用callback,使用asynchronous库,使用promises或者其他方式,但是要避免同步代码,除非你想在服务器上浪费CPU时间。

你应该看一下名为async的库

并尝试使用async.series调用您的问题。

Aredridels的答案相对较好(upvoted),但我认为它缺乏循环等价。 这应该可以帮助你:

同步代码等效:

 while (condition) { var data = request(url); <math here> } return result; 

用于串行执行的asynchronous代码:

 function continueLoop() { if (!condition) return cb(result); request(url, function(err, res, body) { <math here> continueLoop() }) } continueLoop() 

虽然asynchronous风格可能是node.js的本质,一般你不应该这样做,有些时候你想要做到这一点。

我正在写一个方便的脚本来检查一个API,并且不想把它和callback混淆起来。

Javascript不能执行同步请求,但C库可以。

https://github.com/dhruvbird/http-sync