Используя модуль Request npm синхронно в Meteor 1.3
Я пытаюсь использовать пакет запроса npm в Meteor 1.3.2.4 как синхронный.
Основываясь на этой статье руководства Метеор, сначала я пытаюсь использовать 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.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)
Теперь у меня два вопроса:
- Как исправить приведенный выше код?
- Этот подход является лучшим способом использовать модуль запроса npm синхронно в Метеоре, или вы знаете лучший способ?
1 ответ
связывая окружающую среду
Meteor.bindEnvironment
просто убедитесь, что ваш обратный вызов вызывается в контексте, который вы использовали при вызове исходной функции. Это не должно заставить ваш код казаться синхронным. Если вы не использовали его, ваш обратный вызов не будет выполняться внутри оптоволокна (что помешает вам выполнить некоторые действия), и у вас не будет доступа к определенным переменным (таким как текущий пользователь). Crhis Mather предлагает отличное видео на эту тему (имейте в виду, что часть кода немного устарела, но ядро все еще действует).
обертывание асинхронной функции
Meteor.wrapAsync
оборачивает функции, которые ожидают обратный вызов, со стандартной сигнатурой с двумя первыми ошибками Так как request
не придерживаясь этого точного стандарта (он использует обратный вызов с 3 аргументами), пост форума предложил обернуть его функцией, которая ожидает обратный вызов с 2 вышеупомянутыми аргументами.
Соглашение состоит в том, что результатом вызова "обернутой" функции является значение второго аргумента, переданного обратному вызову (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
а также post
):
Например:
import { HTTP } from 'meteor/http';
const result = HTTP.get('https://my-url.com');