[英]Meteor server side. Calling http request inside .then
我需要使用流星构建api方法,该方法应立即返回OK,并在完成长时间的工作后请求一个webhook。
示例代码如下所示
import { Meteor } from 'meteor/meteor';
let Promise = require('bluebird');
Meteor.startup(() => {
Picker.route('/', (params, req, res, next) => {
getAnimalName = Promise.promisify( (cb) => {
setTimeout( () => {
cb(null, "porcupine");
}, 1000);
})()
getAnimalName.then( (name) => {
HTTP.get('https://www.google.ru/#q='+name, (err, res) => {
if(! err){
console.log(res);
}
});
} );
res.end("OK");
});
});
结果我得到这个错误
W20160704-02:14:10.908(3)? (STDERR) Unhandled rejection Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.
W20160704-02:14:10.908(3)? (STDERR) at Object.Meteor._nodeCodeMustBeInFiber (packages/meteor/dynamics_nodejs.js:9:1)
W20160704-02:14:10.909(3)? (STDERR) at Object.Meteor.bindEnvironment (packages/meteor/dynamics_nodejs.js:85:1)
W20160704-02:14:10.909(3)? (STDERR) at Object.call (packages/meteor/helpers.js:117:1)
W20160704-02:14:10.909(3)? (STDERR) at Object.HTTP.get (packages/http/httpcall_common.js:50:20)
W20160704-02:14:10.909(3)? (STDERR) at server/main.js:14:10
W20160704-02:14:10.910(3)? (STDERR) at [object Object]._onTimeout (server/main.js:8:6)
W20160704-02:14:10.910(3)? (STDERR) at Timer.listOnTimeout [as ontimeout] (timers.js:121:15)
W20160704-02:14:10.910(3)? (STDERR) From previous event:
W20160704-02:14:10.911(3)? (STDERR) at server/main.js:12:18
W20160704-02:14:10.911(3)? (STDERR) at doCall (packages/meteorhacks_picker/packages/meteorhacks_picker.js:106:1)
我尝试了不同的操作,例如将HTTP.get
包装到Fiber
,将回调包装到Meteor.bindEnvironment
并包装了多个用于承诺的流星包。 和错误是相同的。 有没有一种方法可以在promise的.then
内发出http请求? (我的代码很大一部分已经按照Promise编写了,我不想在Fiber或其他任何东西中重构它)。 谢谢。
我在Bluebird和Meteor上遇到了同样的问题。 问题是超时。
如果使用超时,请使用Meteor.setTimeout()
或Meteor.bindEnvironment()
。
您自己的超时时间必须修改。 还有一个问题是Bluebird在内部使用setTimeout()
。 Bluebird.promisify()
似乎可以正常工作,但仅使用Meteor随附的内置Promise polyfill可能会更好。
这是您可以使用的Promisify替代品:
function promisify( fn, options ){
return function(){
options = Object.assign( {
context: this,
multiArgs: false
}, options );
let slice = ( arr, i, j ) => Array.prototype.slice.call( arr, i, j );
let args = slice( arguments );
return new Promise(( resolve, reject ) => {
let callback = ( err, val ) => {
if( err != null ){
reject( err );
} else {
resolve( options.multiArgs ? slice( arguments, 1 ) : val );
}
};
args.push( callback );
fn.apply( options.context, args );
});
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.