简体   繁体   English

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

[英]using Request npm module synchronous in Meteor 1.3

I try to use request npm package in Meteor 1.3.2.4 as synchronous.我尝试在 Meteor 1.3.2.4 中使用request npm 包作为同步。

Based onthis Meteor guide article , first I try to use Meteor.bindEnvironment like below:基于此 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;
        }
    }));

But it seems still async call.但它似乎仍然是异步调用。

In next step I try to use Meteor.wrapAsync based on this answer on meteor forum, this is next try code:在下一步中,我尝试根据流星论坛上的这个答案使用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;
        }

This code works fine except request contain error.此代码工作正常,但请求包含错误。 When request contain error (for example url is incorrect) this break with below exception:当请求包含错误(例如 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)

Now I have two question:现在我有两个问题:

  1. How to fix above code?如何修复上面的代码?
  2. Is this approach is the best way to use request npm module synchronous in Meteor or you know better way?这种方法是在 Meteor 中同步使用请求 npm 模块的最佳方法还是您知道更好的方法?

binding the environment绑定环境

Meteor.bindEnvironment simply makes sure that your callback is called in the context you were using when calling the original function. Meteor.bindEnvironment只是确保在调用原始函数时使用的上下文中调用回调。 It does not supposed to make your code appear synchronous.它不应该使您的代码看起来是同步的。 If you did not use it, your callback will not be run inside a fiber (which will prevent you from performing some actions) and you won't have access to certain variables (such as the current user).如果您没有使用它,您的回调将不会在纤程内运行(这将阻止您执行某些操作)并且您将无法访问某些变量(例如当前用户)。 There is an excellent video by Crhis Mather on the subject (keep in mind that some of the code is a bit outdated, but the core is still valid). Chris Mather 有一个关于这个主题的优秀视频(请记住,某些代码有点过时,但核心仍然有效)。

wrapping an async function包装异步函数

Meteor.wrapAsync wraps functions that expect a callback with the standard error-first 2 arguments signature. Meteor.wrapAsync包装函数,这些函数期望具有标准错误前 2 个参数签名的回调。 Since the request does not adhere to this exact standard (it uses a callback with 3 arguments), the forum post suggested wrapping it with a function that expects a callback with the aforementioned 2 arguments.由于request不符合这个确切的标准(它使用带有 3 个参数的回调),论坛帖子建议用一个函数包装它,该函数需要一个带有上述 2 个参数的回调。

The convention is that the result of calling a "wrapped" function is the value of the second argument passed to the callback (the data ), and an error is thrown if there is one.约定是调用“包装”函数的结果是传递给回调的第二个参数( data )的值,如果有则抛出错误。

Therefore, as it is now, you can wrap the function with a try..catch block and see if there is an error.因此,就像现在一样,您可以使用try..catch块包装该函数并查看是否有错误。

Another option is to never raise an error:另一种选择是永远不会引发错误:

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

Which will always result in a {response, body, error} object, where error will be null if there is no error.这将始终导致{response, body, error}对象,如果没有错误,则error将为null

using the http package使用 http 包

I think that the http package is perfectly valid and does pretty much the same for you with convenience methods (eg, the general call , and specific get and post ):我认为http包是完全有效的,并且使用方便的方法(例如,通用call和特定的getpost )对您几乎相同:

For example:例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM