在Meteor 1.3中使用Request npm模块同步

我尝试使用Meteor 1.3.2.4中的请求npm包作为同步。

基于这个Meteor指南文章 ,首先我尝试使用Meteor.bindEnvironment如下所示:

  import request from 'request'; let result = {success: false, error: null, content: ""}; let requestOptions = { url: <MY-URL-HERE> }; request(requestOptions, Meteor.bindEnvironment((error, response, html) => { if (!error && response.statusCode == 200) { result.success = true; result.content = html; result.error = null; } else { result.success = false; result.content = ""; result.error = error; } })); 

但似乎仍然是asynchronous调用。

在下一步我尝试在meteor论坛上基于这个答案使用Meteor.wrapAsync ,这是下一个尝试代码:

  import request from 'request'; let result = {success: false, error: null, content: ""}; let requestOptions = { url: <MY-URL-HERE> }; let func = function (options, callback) { request(options, function (error, response, body) { console.log("error: " + JSON.stringify(error)); console.log("response: " + JSON.stringify(response)); console.log("body: " + JSON.stringify(body)); callback(error, {response, body}); }); }; let {error, response, body} = syncRequest(requestOptions); console.log("error2: " + JSON.stringify(error)); console.log("response2: " + JSON.stringify(response)); console.log("body2: " + JSON.stringify(body)); if (response.statusCode == 200) { result.success = true; result.content = body; result.error = null; } else { result.success = false; result.content = ""; result.error = error; } 

除了请求包含错误,此代码工作正常。 当请求包含错误(例如url不正确),这个突破与下面的exception:

 I20160518-08:24:22.180(4.5)? error: {} I20160518-08:24:22.181(4.5)? response: undefined I20160518-08:24:22.182(4.5)? body: undefined W20160518-08:24:22.839(4.5)? (STDERR) TypeError: The header content contains invalid characters W20160518-08:24:22.839(4.5)? (STDERR) at Object.Future.wait (/home/cyc/.meteor/packages/meteor-tool/.1.3.2_4.7bk6xv++os.linux.x86_64+web.browser+web.cordova/mt-os.linux.x86_64/dev_bundle/server-lib/node_modules/fibers/future.js:420:15) W20160518-08:24:22.839(4.5)? (STDERR) at packages/meteor/helpers.js:119:1 W20160518-08:24:22.839(4.5)? (STDERR) at Object.getContent (server/lib/get_content.js:51:26) W20160518-08:24:22.839(4.5)? (STDERR) at Object.fetch (server/lib/get_content.js:205:27) W20160518-08:24:22.839(4.5)? (STDERR) at Object.fetchSource (server/lib/get_content.js:369:31) W20160518-08:24:22.840(4.5)? (STDERR) at [object Object].action (server/controller/postsController.js:79:39) W20160518-08:24:22.840(4.5)? (STDERR) at [object Object].handle (packages/iron_middleware-stack/lib/handler.js:74:1) W20160518-08:24:22.840(4.5)? (STDERR) at boundNext (packages/iron_middleware-stack/lib/middleware_stack.js:251:1) W20160518-08:24:22.840(4.5)? (STDERR) at runWithEnvironment (packages/meteor/dynamics_nodejs.js:110:1) W20160518-08:24:22.840(4.5)? (STDERR) at packages/meteor/dynamics_nodejs.js:123:1 W20160518-08:24:22.840(4.5)? (STDERR) - - - - - W20160518-08:24:22.840(4.5)? (STDERR) at ClientRequest.OutgoingMessage.setHeader (http.js:733:13) W20160518-08:24:22.840(4.5)? (STDERR) at new ClientRequest (http.js:1429:14) W20160518-08:24:22.840(4.5)? (STDERR) at Object.exports.request (http.js:1899:10) W20160518-08:24:22.841(4.5)? (STDERR) at Request.start (/home/cyc/Programming/Projects/content/Sources/node_modules/request/request.js:753:32) W20160518-08:24:22.841(4.5)? (STDERR) at Request.end (/home/cyc/Programming/Projects/content/Sources/node_modules/request/request.js:1418:10) W20160518-08:24:22.841(4.5)? (STDERR) at end (/home/cyc/Programming/Projects/content/Sources/node_modules/request/request.js:580:14) W20160518-08:24:22.841(4.5)? (STDERR) at Object._onImmediate (/home/cyc/Programming/Projects/content/Sources/node_modules/request/request.js:594:7) W20160518-08:24:22.841(4.5)? (STDERR) at processImmediate [as _immediateCallback] (timers.js:363:15) 

现在我有两个问题:

  1. 如何解决上面的代码?
  2. 这种方法是在meteor中使用请求npm模块同步的最好方法还是你知道更好的方法?

约束环境

Meteor.bindEnvironment只是确保您在调用原始函数时使用的上下文中调用了callback。 它不应该使您的代码显示同步。 如果你没有使用它,你的callback将不会在光纤中运行(这将阻止你执行一些操作),你将无法访问某些variables(如当前用户)。 Crhis Mather在这个主题上有一个很棒的video (记住一些代码已经过时了,但是核心仍然有效)。

包装一个asynchronousfunction

Meteor.wrapAsync包装的函数需要使用标准的error-first 2参数签名进行callback。 由于request不符合这个确切的标准(它使用了一个带有3个参数的callback函数),所以论坛postbuild议用一个函数来包装它,这个函数需要使用上述2个参数进行callback。

约定是,调用“包装”函数的结果是传递给callback( data )的第二个参数的值,如果有的话会抛出一个错误。

因此,就像现在一样,你可以用try..catch块封装函数,看看是否有错误。

另一个select是不要提出错误:

 let func = function (options, callback) { request(options, function (error, response, body) { callback(null, {response, body, error}); }); }; 

这总是会导致{response, body, error}对象,如果没有错误,那么error将是null

使用http包

我认为http包是完全有效的,并且对于使用便捷方法(例如,一般call和特定的getpost )来说,几乎是一样的:

例如:

 import { HTTP } from 'meteor/http'; const result = HTTP.get('https://my-url.com');