2017-04-19 11 views
5

ノード7/8の非同期/待機のサポートを含む以下の修正Restifyの例を見てみましょう。ノード7非同期/ Awaitでコントローラを復元する

私はExpress/Restify/etcにこれを適切に実装することに多少の懸念があります。私の懸念事項は、予定よりも長い間イベントループにぶら下がっている約束事です...私はこれがまさに約束ではないことを知っていますが、この実装について心配すべきですか?私はまだ何か問題に気づいていない。

'use strict'; 

const restify = require('restify'); 
const User = require('./models/User'); 

const server = restify.createServer({ 
    name: 'myapp', 
    version: '1.0.0' 
}); 

server.use(restify.acceptParser(server.acceptable)); 
server.use(restify.queryParser()); 
server.use(restify.bodyParser()); 

server.get('/echo/:name', async function (req, res, next) { 
    try { 
    const user = await User.findOne({ 
     name: req.params.name; 
    }); 
    res.send(user.get({plain: true})); 
    } catch (error) { 
    console.error(error); 
    res.send(500); 
    } 
    return next(); 
}); 

server.listen(8080, function() { 
    console.log('%s listening at %s', server.name, server.url); 
}); 

答えて

0

エラーは異なる方法で処理されるコールバックを受け入れ、通常の関数の代わりにasync機能を使用して問題があります。

コールバック関数(別名「err-backs」)では、コールバックは、実行が成功したかどうかにかかわらず、コールする必要があります。最初のパラメータはエラーオブジェクトです。

async関数は、エラー(同期または非同期)の場合に拒否された約束を返します。

デフォルトでは、Express.js/Restifyは通常のエラーバックを想定しています。 async関数を代わりに渡して失敗した場合、Express.js/Restifyは拒否された約束を無視して呼び出されるのを待っています。それは返された約束を意識しておらず、それを扱っていないだけです。 最後に、コールバックはまったく呼び出されず、エンドポイントはタイムアウトします。

エラーを正しく処理することはできません。

あなたはそれを試してみることができます:

server.get('/echo/:name', async function (req, res, next) { 
    throw new Error(); 
}); 

だから経験則として、私はコンセプトを混在しないと非同期関数にコールバックを渡すことはありませんお勧めします。これは赤い旗です。あなたは、たとえば次のようにラッパーを使用する必要があり、この問題を解決するために

は:

const wrap = function(fn) { 
 
    return function(req, res, next) { 
 
     return fn(req, res, next).catch(function(err) { 
 
      return next(err); 
 
     }); 
 
    }; 
 
}; 
 
server.get('/echo/:name', wrap(async function (req, res, next) { 
 
    throw new Error(); 
 
}));

あなたは適切なステータスコードを取得し、タイムアウトはもう存在しません。

あなたはそれを自分でラップしたくない場合に使用できるモジュールのカップルもあります

関連する問題