在返回之前等待异步完成

时间:2013-04-01 02:14:57

标签: node.js asynchronous mongoose

mongoosejs异步代码。

    userSchema.static('alreadyExists',function(name){
    var isPresent;
        this.count({alias : name },function(err,count){
        isPresent = !!count
        });
    console.log('Value of flag '+isPresent);
    return isPresent;
}); 

我知道isPresent在this.count异步函数调用回调之前返回,因此它的值是未定义的。但是我如何等待回调改变isPresent的值然后安全返回呢?

效果如何 (function(){ asynccalls() asynccall() })();在异步流程中有。 var foo = asynccall() or (function(){})()会发生什么 以上两个会让回程等待吗?

可以process.nextTick()帮忙吗?

我知道有很多像这样的问题,但没有解释异步完成前返回的问题

2 个答案:

答案 0 :(得分:2)

没有办法做到这一点。您需要更改函数的签名以进行回调,而不是返回值。

使IO异步是Node.js的主要动机之一,等待异步调用完成将失败目的。

如果你给我更多关于你想要实现的内容的话,我可以给你指点如何用回调来实现它。

编辑:您需要以下内容:

userSchema.static('alreadyExists',function (name, callback) {
    this.count({alias : name}, function (err, count) {
        callback(err, err ? null : !!count);
        console.log('Value of flag ' + !!count);     
    });
});

然后,您可以像:

一样使用它
User.alreadyExists('username', function (err, exists) {
    if (err) {
        // Handle error
        return;
    }

    if (exists) {
        // Pick another username.
    } else {
        // Continue with this username.
    }
}

答案 1 :(得分:0)

有同样的问题。我希望我的mocha测试运行得非常快(就像他们最初的那样),但同时在我的应用程序中有一个反DOS层存在并可操作。像他们最初工作一样运行这些测试是疯狂的快速和我正在使用的ddos模块开始响应Too Many Requests错误,使测试失败。我不想仅仅为了测试目的而禁用它(我实际上想要进行自动化测试来验证太多的请求案例)。

我为所有为HTTPS请求准备客户端的测试使用了一个地方(填充了正确的标题,经过身份验证,使用了Cookie等)。它或多或少看起来像这样:

var agent = thiz.getAgent();
thiz.log('preReq for user ' + thiz.username);
thiz.log('preReq for ' + req.url + ' for agent ' + agent.mochaname);

if(thiz.headers) {
    Object.keys(thiz.headers).map(function(header) {
        thiz.log('preReq header ' + header);
        req.set(header, thiz.headers[header]);
    });
}
agent.attachCookies(req);

所以我想在那里注入一个睡眠,这个睡眠每5次就会被测试请求执行一个请求 - 所以整个套件会快速运行,每个第5个请求都会等待ddos模块考虑我的请求因Too Many Requests错误而无法解决。

我搜索了大部分有关Async和其他库或实践的条目。所有这些都需要进行回调 - 这意味着我将不得不重新编写几百个测试用例。

最后,我放弃了任何优雅的解决方案,并落到了适合我的那个。这是添加一个for循环试图检查不存在的文件的状态。它导致操作执行的时间足够长,我可以将其校准持续约6500毫秒。

for(var i = 0; i < 200000; ++i) {
    try {
        fs.statSync('/path' + i);
    } catch(err) {
    }
};