我需要使用meteor构建api方法,该方法应该立即返回OK并在长时间工作完成后请求webhook。
示例代码如下所示
CREATE TABLE cars (
car_id SMALLINT
, car_type VARCHAR(255)
);
INSERT INTO cars (car_id, car_type)
VALUES
(1, 'bmw')
, (2, 'mercedes')
, (3, 'pinto')
, (4, 'corolla');
SELECT car_id FROM cars
WHERE car_type IN ('bmw', 'mercedes', 'pinto'); -- Returns Values : 1, 2, 3
结果我收到此错误
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
以及几个用于承诺的流星包。错误是一样的。有没有办法在promise Meteor.bindEnvironment
中创建一个http请求? (我的代码的很大一部分已经按照承诺编写,我不想在Fiber或其他任何内容中重构它)。感谢。
答案 0 :(得分:0)
我遇到了与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 );
});
};
}