web-dev-qa-db-ja.com

ブルーバードの警告「ハンドラーでプロミスが作成されましたが、ハンドラーから返されませんでした」

Bluebirdから作成したプロミスを返さないという警告が表示されますが、コードを書き直す理由と方法を理解できません。

(私は Bluebird API ページと アンチパターンページ で警告について読んでみましたが、これは私がやっていることだと思います)

私のview.jsファイルで:

var express = require('express'),
    router = express.Router(),
    settings = myReq('config/settings'),
    Sets = myReq('lib/Sets'),
    log = myReq('lib/utils').getLogger('View');

router.get('/:setId/', function(req, res, next) {
    var
        setId = req.params.setId,  
        user = req.user,
        set = new Sets(setId, user);

    log.info('Got a request for set: ' + setId);

    // The below line gives the warning mentioned
    set.getSet().then(function(output) {
        res.send(output);

    }).error(function(e){
        log.error(e.message, e.data);
        res.send('An error occurred while handling set:' + e.message);
    });

});

module.exports = router;

私のSets.jsファイルには、

var
    Promise = require('bluebird'),
    OE = Promise.OperationalError,
    settings = myReq('config/settings'),
    UserData = myReq('lib/userData'),
    log = myReq('lib/utils').getLogger('sets'),
    errorToSend = false;

module.exports = function(setId, user) {
    var 
        sets = myReq('lib/utils').getDb('sets');

    return {

        getSet : function() {

            log.debug('Getting set')

            return sets.findOneAsync({
                setId:setId
            }).then(function(set){
                if ( set ) {
                    log.debug('got set from DB');
                } else {
                    set = getStaticSet(setId);
                    if ( ! set ) {
                        throw new OE('Failed getting db records or static template for set: ' + setId );
                    }
                    log.debug('got static set');
                }

                log.debug('I am handling set')

                if ( ! checkSet(set) ) {
                    var e = new OE('Failed checking set');
                    e.data = set;
                    throw e;
                }

                return {
                    view : getView(set),
                    logic : set.logic,
                    canEdit : true,
                    error : errorToSend
                };

            });
        }
    };
};

したがって、 "set.getSet()"を含む私のview.jsファイルの行は、作成されたpromiseを返さないという警告を与えます。このスクリプトはまだ期待どおりの動作をしているようですが、警告が表示される理由がわかりません。

スタックトレース:

Warning: a promise was created in a handler but was not returned from it
    at Object.getSet (C:\dev\infoscrn\lib\Sets.js:36:25)
    at C:\dev\infoscrn\routes\view.js:39:20
    at Layer.handle [as handle_request] (C:\dev\infoscrn\node_modules\express\lib\router\layer.js:82:5)
    at next (C:\dev\infoscrn\node_modules\express\lib\router\route.js:110:13)
    at Route.dispatch (C:\dev\infoscrn\node_modules\express\lib\router\route.js:91:3)
    at Layer.handle [as handle_request] (C:\dev\infoscrn\node_modules\express\lib\router\layer.js:82:5)
    at C:\dev\infoscrn\node_modules\express\lib\router\index.js:267:22
    at param (C:\dev\infoscrn\node_modules\express\lib\router\index.js:340:14)
    at param (C:\dev\infoscrn\node_modules\express\lib\router\index.js:356:14)
    at Function.proto.process_params (C:\dev\infoscrn\node_modules\express\lib\router\index.js:400:3)
    at next (C:\dev\infoscrn\node_modules\express\lib\router\index.js:261:10)
    at Function.proto.handle (C:\dev\infoscrn\node_modules\express\lib\router\index.js:166:3)
    at router (C:\dev\infoscrn\node_modules\express\lib\router\index.js:35:12)
    at Layer.handle [as handle_request] (C:\dev\infoscrn\node_modules\express\lib\router\layer.js:82:5)
    at trim_prefix (C:\dev\infoscrn\node_modules\express\lib\router\index.js:302:13)
    at C:\dev\infoscrn\node_modules\express\lib\router\index.js:270:7
    at Function.proto.process_params (C:\dev\infoscrn\node_modules\express\lib\router\index.js:321:12)
    at next (C:\dev\infoscrn\node_modules\express\lib\router\index.js:261:10)
    at C:\dev\infoscrn\node_modules\express\lib\router\index.js:603:15
    at next (C:\dev\infoscrn\node_modules\express\lib\router\index.js:246:14)
19

まず、試してみてください すべての依存関係を更新 。 Bluebirdの最近のバージョンがあり、 この警告に関する問題 を修正しました。

次に、必ず すべてのハンドラーから戻る を確認してください。

次に、まだ警告が表示される場合(私と同じように) この特定の警告を無効にする 私は自分の環境でBLUEBIRD_W_FORGOTTEN_RETURN=0を設定することでそうすることを選択しました。

12
Gunar Gessner

警告を無効にしないでください。理由があるのです。

典型的なパターンは、onfulfillまたはonrejectハンドラーがPromiseを構築する場合、ハンドラーからそのPromise(またはそこから派生したチェーン)を返し、チェーンがそのPromiseの状態を採用するようにします。

したがって、Bluebirdは、ハンドラー関数の1つが実行されているときを追跡し、Promiseコンストラクターが呼び出されたときを追跡しています。ハンドラーの実行中にany pointでPromiseが作成されたと判断した場合(コールスタック内のどこかに含まれる)、Promiseがハンドラーから返されたnotだった場合、おそらくforgotがreturnステートメントを書くと考えているため、この警告が発行されます。

したがって、ハンドラー内で作成されたPromiseを正当に気にしない場合は、ハンドラーから明示的に何かを返すだけで済みます。ハンドラーから何が返されるかを気にしない場合(つまり、Promiseが満たす値を気にしない場合)は、単にnullを返します。何を返す場合でも、明示的な戻り(具体的には、undefined以外の戻り値)は、Bluebirdに、何をしているのかわかっていると伝え、この警告は発行しません。

10
brianmearns

あなたがreturnステートメントを持っているすべての場所が私にとってうまくいくことを確認してください。

0