无法从Meteor.setTimeout的Server方法返回

时间:2016-08-09 17:00:46

标签: meteor methods

在我的项目中,我需要远程检查一个API,我想要做一次,如果它返回我不想要的东西,它必须检查另一个时间但是在5秒延迟之后,然后是10,然后是15然后30秒。如果在30秒之后仍然没有我期望的API响应,那么我向客户端抛出一个错误,但是如果API回答我想要的预期响应(在检查#1或#2或#3或#4)返回一些东西给客户并停止检查。

这是我的方法:

Meteor.methods({
    'verifyUserOwnership': function() {
        function checkCard() {
            return false; // for testing, simulating the bad answer from api
        }

        var checkOwnership = function(nbrTry, delay){
            if (checkCard()) {
              //I will do something if API responds with wwhat I want 
            } else {
                if(nbrTry < 3){
                    delay +=5000;
                    Meteor.setTimeout(function(){checkOwnership(nbrTry+1, delay);}, delay);
                } else {
                    throw new Meteor.Error('Card could not be found' );// has to be sent to client if after all the tries, API did respond with somwthing bad
                }
            }
        }
        checkOwnership(0, 0);
    }
});

但是使用这段代码我有这个错误:

I20160809-12:56:06.928(-4)? Exception in setTimeout callback: Error:      [Card could not be found]
I20160809-12:56:06.929(-4)?     at checkOwnership     (server/methods.js:74:17)
I20160809-12:56:06.929(-4)?     at server/methods.js:72:40
I20160809-12:56:06.929(-4)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20160809-12:56:06.929(-4)?     at packages/meteor/timers.js:6:1
I20160809-12:56:06.930(-4)?     at runWithEnvironment (packages/meteor/dynamics_nodejs.js:110:1)

我认为这与光纤和Meteor.bindEnvironment有关,但我不知道该怎么做。

谢谢。

1 个答案:

答案 0 :(得分:0)

使用节点光纤来停止/限制递归回调,直到它们返回值。所以你模仿阻止。

首先在你的meteor app dir install:meteor npm install --save fiber

然后改变你的代码:

if (Meteor.isServer) {
var Future = Npm.require('fibers/future');


Meteor.methods({
    'verifyUserOwnership': function() {
        var fut = new Future();
        function checkCard() {
            return false; // for testing, simulating the bad answer from api
        }

        var checkOwnership = function(nbrTry, delay){
            if (checkCard()) {
              //I will do something if API responds with wwhat I want 
            } else {
                if(nbrTry < 3){
                    delay +=5000;
                    nbrTry +=1;
                    console.log(nbrTry)
                    console.log("out")
                    Meteor.setTimeout(function(){
                        console.log("in")
                        checkOwnership(nbrTry, delay);
                        fut.return('done');
                        return 'done';
                    }, delay);
                } else {
                    console.log('err');
                    throw new Meteor.Error('Card could not be found' );// has to be sent to client if after all the tries, API did respond with somwthing bad
                }
            }
        }
        if (nbrTry = 0)
            console.log("call")
            checkOwnership(0,0);
    }
});
}

并注意到您的代码现在必须运行服务器端。检查日志服务器端!

此代码确实返回错误:错误:Future解决了多次

但链条中返回的最终错误符合您的条件:[无法找到卡片]

另见this link