【问题标题】:Meteor server side. Calling http request inside .then流星服务器端。在 .then 中调用 http 请求
【发布时间】:2016-07-06 01:38:39
【问题描述】:

我需要使用流星构建 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 或其他方式重构它)。谢谢。

【问题讨论】:

    标签: javascript meteor promise


    【解决方案1】:

    我在使用 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 );
        });
      };
    }
    

    【讨论】:

      猜你喜欢
      • 2013-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多