流星服务器端。在.then里面调用http请求

时间:2016-07-03 23:52:48

标签: javascript meteor promise

我需要使用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或其他任何内容中重构它)。感谢。

1 个答案:

答案 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 );
    });
  };
}