2016-09-21 13 views
1

私は現在、ユーザー自身のWebサーバーに統合されるAPI /ルーターを開発中です。私のコードは必要な作業を行いますが、このスニペットのように後で自分のロジックを実装することもできます:myApi.on('action', (err, result, req, res) => {/*user's logic here*/})コールバックパラメータを含まない関数を約束する方法は?

私のコードは、ユーザーがデフォルトの動作を上書きして独自のロジックを実装することを決定した場合、応答を終了しません。これは、要求および応答が、ユーザによって必要に応じて次のミドルウェア機能に落ちることを可能にするためである。私が望む

制御フローは次のようになります。応答がない持っている場合

  1. は、次のミドルウェア機能に私の最初のルートロジック

  2. を実行し、ユーザーのカスタム・ロジック

  3. パス制御を実行します終了しました

ユーザーは非同期ロジックを実装する必要があります。私は、次のミドルウェア機能にコントロールを渡す前に、ユーザーのカスタムロジックが終了することを許可する方法がありません。私はそれが私が設定したインターフェースのためだと信じています。ユーザーができるだけ忙しい仕事をしたいと思っています。これは、私が自分のロジックのすべてのエンドポイントで呼び出す必要があるcallback()またはnext()関数に相当するものをユーザに渡すことを好まないことを意味します(私のルータにはいくつかの異なるルートが含まれています)。

私はpromisify-nodeのような有望なラッパーを調べましたが、最終的な引数としてコールバックを取る関数しかラッピングできないようです。私はまた、ユーザーがカスタム実装から約束を返すように要求していると考えましたが、それはビジーワーク/定型コードを必要としないという私の望みに反するものです。

約束を使用する方法はありますか?または他の構成を使用していますか?この非同期問題をユーザーに苦痛を与えることなく処理できますか?

+0

リクエストが終了したことをどのように定義しますか? – Amit

+0

@Amit、私は要求と応答を切り替えたようです。 res.finishedタグをチェックして**レスポンス**が終了したかどうか確認します。 – TheKingOfTyrants

答えて

1

いいえ、コールバックを取らない関数を宣言することはできません。このような関数は非同期ではなく、終了時を知るための方法を提供していません。あなたは不運です。

私の問題は、非同期ロジックを実装したい場合に発生します。

非同期なものを実装したい場合、ユーザーが約束を返す関数を渡すようにしてください。それはおそらく彼に、私はあなたがユーザーのカスタム関数の戻り値を調べます質問を理解していれば

const myApi = { 
    on(name, fn) { 
     Promise.resolve(result) // or whenever you need to run the user logic 
     .then(result => 
      fn(req, result) // or whatever you want to pass 
     ) 
     .then(customresult => { 
      res.write(customresult); // or whatever you want to do with its result 
     }); 
    } 
}; 

myApi.on('action', (req, result) => { 
    // user's logic here 
    // throw exceptions 
    // return values 
    // return promises for values 
    // or whatever the user needs to do 
}) 
0

:-)とにかく約束で動作するようになる好意を行います。 約束のようなオブジェクトの場合は、移動する前に解決するまで待つことができます。これは、ユーザーのカスタムミドルウェアにnext関数を渡すのと同じです。あなたの例では

人のユーザがそうのようなあなたのAPIを使用します。

myApi.on('action', (err, result, req, res) => { 
    return myPromiseAwareAsyncFunction(); 
}) 

そして、あなたのコードに:あなたは、両方の約束を提供したい場合

let userMiddleWare = lookupNextActionHandler(); 
let result = userMiddleWare(err, result, req, res); 
// Wrap any value (promise or not) in a promise 
Promise.resolve(result) 
    .then(result => { 
    // Move on to next middle ware 
    }) 
    .catch(error => { 
    console.error(error); 
    process.exit(1); // Or what ever you use 
        // to end the middle ware chain. 
    }); 

nextコールバックでは次のようなことができます:

let userMiddleWare = lookupNextActionHandler(); 
new Promise((resolve, reject) => { 
    function next(err) { 
    if (err) { 
     reject(err); 
    } else { 
     resolve(); 
    } 
    } 
    let result = userMiddleWare(err, result, req, res, next); 
    Promise.resolve(result).then(resolve).catch(reject); 
}) 
.then(result => { 
    // Move on to next middle ware 
}) 
.catch(error => { 
    console.error(error); 
    process.exit(1); // Or what ever you use 
        // to end the middle ware chain. 
}); 

プロミスは1つの解像度しか扱うことができないので、これが機能し、ユーザが(nextを返すかプロミスを返す)これまでどおり動作するでしょう。

関連する問題