繁体   English   中英

流星服务器端。 在.then内部调用http请求

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM