在Meteor 1.3中使用请求npm模块同步

时间:2016-05-31 04:25:04

标签: javascript node.js meteor npm npm-request

我尝试在Meteor 1.3.2.4中使用request npm package作为同步。

根据this Meteor guide article,我首先尝试使用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;
        }
    }));

但似乎仍然是异步电话。

在下一步中,我尝试在meteor论坛上使用基于this answerMeteor.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不正确)时,这会中断以下异常:

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模块同步的最佳方法还是你知道更好的方法?

1 个答案:

答案 0 :(得分:2)

绑定环境

Meteor.bindEnvironment只需确保在调用原始函数时使用的上下文中调用回调。它不应该使您的代码看起来是同步的。如果您没有使用它,您的回调将不会在光纤内运行(这将阻止您执行某些操作)并且您将无法访问某些变量(例如当前用户)。 Crhis Mather有一个excellent video关于这个主题(请记住,有些代码有点过时,但核心仍然有效)。

包装异步函数

Meteor.wrapAsync包含期望使用标准的error-first 2 arguments签名进行回调的函数。由于request不符合这个确切的标准(它使用带有3个参数的回调),因此论坛帖子建议用一个函数来包装它,该函数需要使用前面提到的2个参数进行回调。

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

因此,就像现在一样,您可以使用try..catch块包装函数并查看是否存在错误。

另一个选择是永远不会引发错误:

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

这将始终生成{response, body, error}个对象,如果没有错误,error将为null

使用http包

我认为http包非常有效,并且使用便捷方法(例如,一般call,特定get和{{1}对您来说几乎完全相同}):

例如:

post