等待异步完成后再返回

Posted

技术标签:

【中文标题】等待异步完成后再返回【英文标题】:wait for async to complete before return 【发布时间】:2013-03-22 03:14:02 【问题描述】:

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() or (function())() 会发生什么 以上两个会让return等待吗?

process.nextTick() 可以帮忙吗?

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

【问题讨论】:

【参考方案1】:

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

使 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 是一个检查用户给定的别名是否已经存在于 db 中的函数,如果存在,他会得到一个注释以选择另一个。 如果他们想在 db 中检查一些东西然后根据结果继续,该怎么办? 感谢您的更新! .这清除了很多事情,尤其是等待有多糟糕,而且我对回调的力量一无所知【参考方案2】:

遇到了同样的问题。我希望我的 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 次该客户端被测试请求以执行请求 - 所以整个套件将快速运行,并且每 5 个请求将等待让 ddos​​ 模块考虑我的请求因 Too Many Requests 错误而无法惩罚。

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

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

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

【讨论】:

以上是关于等待异步完成后再返回的主要内容,如果未能解决你的问题,请参考以下文章

如何使“主线程”等待“子线程”执行结束后再继续执行

等待异步任务完成后再继续?

笑话:等待异步测试完成后再运行下一个测试

js Promise 等待多个异步操作执行完再去做一些操作

如何使“主线程”等待“子线程”执行结束后再继续执行

架构笔记[一]:同步与异步