【问题标题】: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() 可以帮忙吗?

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

【问题讨论】:

    标签: node.js asynchronous mongoose


    【解决方案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) {
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      • 1970-01-01
      • 2020-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多