3

Mocha と Should.js を使用して Node.js/Express/Mongoose プロジェクトのテストを書いており、MongoDB にアクセスする関数をテストしています。これらのテストをデータベース内の実際のレコードから完全に独立させたいので、エントリを作成してロードし、すべてのテストを実行してから削除します。create関数にコールバックがないように、実際の関数を作成しました (プロジェクト全体が完了した後にテストを作成しています)。完了したら、ページをレンダリングするだけです。テスト スクリプトでは、 を呼び出したload_entry後に関数を呼び出しますが、通常よりも時間がかかるcreateことがあるため、createload_entryまだ作成されていないため、記事を実際に読み込めない場合、エラーをスローします。コールバックを使用せずに非同期関数を確実に終了させる方法はありますか?

他に提供できる情報があれば教えてください。ほとんどの解決策は単に「コールバックを使用してください!」と言うだけなので、Google をくまなく調べましたが、私の質問に本当に答えているものは見つかりませんでした。

4

4 に答える 4

5

として知られているものを使用します。promise

詳細については、こちらをご覧ください。

これを行うことができる優れたライブラリがたくさんあります。

Q.jsは私が個人的に気に入っているもので、最近は広く使われています。Promise はjQueryにも存在します。

json-p非同期呼び出しで aq promise を使用する例を次に示します: 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

うまくいく解決策を見つけました。私がしたことは、関数 ( 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 に答える
0

非同期処理をネイティブで行う唯一の方法はsetTimeout、 、setIntervalおよびaddEventListenerであり、これらはすべてコールバックを受け取るため、最終的にはどこかでコールバックを使用する必要があります。

ただし、Deferred としても知られる Promises/A を使用することで、それを隠すことができます。

コードは次のようになります。

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

then-chaining の使用:

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 に答える