3

我正在使用 Mocha 和 Should.js 为我的 Node.js/Express/Mongoose 项目编写测试,并且我正在测试访问我的 MongoDB 的函数。我希望这些测试完全独立于我的数据库中的实际记录,所以我想创建一个条目然后加载它,并对其进行所有测试,然后将其删除。我写了我的实际函数(我在整个项目完成后编写测试),这样create函数就没有回调;它只是在完成后呈现一个页面。在我的测试脚本中,我在调用load_entry后调用我的函数create,但有时create需要比平时更长的时间,因此load_entry当它实际上无法加载文章时引发错误,因为它尚未创建。有什么方法可以确保异步函数在不使用回调的情况下完成?

如果我可以提供更多信息,请告诉我。我浏览了整个谷歌,找不到任何真正回答我问题的东西,因为大多数解决方案只是说“使用回调!”

4

4 回答 4

5

使用所谓的promise

你可以在这里阅读更多关于它的信息。

有很多很棒的库可以为您做到这一点。

Q.js是我个人喜欢的一种,现在被广泛使用。Promise 也存在于jQuery中。

下面是一个使用 aq promise 和异步json-p调用的例子:DEMO

var time;
$.ajax({
    dataType: 'jsonp',
    type: 'GET',
    url: "http://www.timeapi.org/utc/now.json",
    success: function (data) {
        time = data;
    },
    error: function (data) {
        console.log("failed");
    }
})
.then(function(){ // use a promise library to make sure we synchronize off the jsonp
    console.log(time);    
});
于 2013-08-09T15:46:33.243 回答
1

这绝对是您想要回调的那种事情。除此之外,您将不得不编写某种回调包装器来轮询数据库以确定何时完成创建相关记录,然后发出事件或执行其他异步操作以允许测试继续。

于 2013-08-09T15:46:37.930 回答
0

由于执行异步操作的唯一本机方法是:和setTimeout,并且它们都接受回调,因此您最终将不得不在某处使用回调。setIntervaladdEventListener

但是,您可以使用 Promises/A(也称为 Deferreds)来隐藏它。

您的代码可能如下所示:

db.create_entry("foo", data).done(function (entry) {
    db.delete_entry(entry).done(function () {
        console.log("entry is deleted");
    });
});

使用然后链接:

db.create_entry("foo", data).then(function (entry) {
    return db.delete_entry(entry);
}).done(function () {
    console.log("entry is deleted");
});;
于 2013-08-09T15:46:42.883 回答
0

我找到了一个可行的解决方案。我所做的是向我的函数 ( next) 添加一个回调,并且仅在指定时调用它(即,用于测试):

//more stuff above
article.save(function(err){
    if (!err) {
        console.log(req.user.username + ' wrote ' + article.slug)
        return next() || res.redirect('/admin')
    }
    return next(err) || res.render('articles/entry_form', {
        title: 'New Entry',
        article: article,
    })
})

这样,当我运行实际的服务器并且没有指定回调时,它不会抛出错误,因为它只会返回res.render语句。

于 2013-08-09T16:17:11.607 回答