等待异步完成后再返回

3

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 异步函数调用回调之前被返回,所以它的值是 undefined。但是我该如何等待回调改变 isPresent 的值,然后安全地返回?
(function(){ asynccalls() asynccall() })(); 对异步流程有什么影响?如果 var foo = asynccall() 或 (function(){})() 会发生什么?以上两个会让返回等待吗? process.nextTick() 能帮助吗?
我知道有很多类似这样的问题,但没有一个解释了在异步完成之前返回的问题。
2个回答

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.
    }
}

alreadyExists 是一个函数,用于检查用户提供的别名是否已经存在于数据库中,如果存在,则会收到提示选择其他别名。 - Rana Deep
如果想要在数据库中检查某些内容并根据结果继续进行,应该怎么做? - Rana Deep
谢谢更新!这解决了很多问题,特别是让我意识到等待的糟糕程度以及回调函数的强大作用。 - Rana Deep

0

遇到了同样的问题。我希望我的mocha测试能够运行得非常快(就像它们最初那样),但同时也要在我的应用程序中有一个反DOS层存在和运行。以原来的方式运行这些测试非常快,而我使用的ddos模块开始响应Too Many Requests错误,导致测试失败。我不想仅仅为了测试目的而禁用它(实际上,我希望有自动化测试来验证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个请求都将等待,使ddos模块认为我的请求不会受到Too Many Requests错误的惩罚。

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

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接