4

別の promise が失敗した場合にのみpromise を返す方法を探しています。

どうやってやるの?

私が持っている約束は次のようになります(もちろん、関連のないコードは削除しました):

getUserByUsername = function(username) {
    return promise(function(resolve, reject) {
       user = userModel.getByUsername(username);
       if ( user ) { resolve(user); } else { reject("user not found"); }
    });
};

getUserByEmail = function(email) {
    return promise(function(resolve, reject) {
       user = userModel.getByEmail(email);
       if ( user ) { resolve(user); } else { reject("user not found"); }
    });
};

checkPassword = function(user, password) {
    return promise(function(resolve, reject) {
       if ( user.isValidPassword(password) ) { resolve() } else { reject("password mismatch"); }
    });
};

そして、次の順序でそれらを組み合わせたい

  1. 呼び出しgetUserByUsername、拒否された場合は呼び出しgetUserByEmail
  2. 上記の 2 つのプロミスから解決した人の値を返します。または、両方のプロミスが失敗した場合は、チェーン全体を拒否します。
  3. 値を指定して呼び出しcheckPassword、拒否された場合はチェーン全体を拒否します

これまでのところ、私はこれを行ってきましたが、うまくいくようです。(私はwhen.jsを使用しています)

getUserByUsername(usernameOrEmail)
.then( 
    function(user) { return user; }, 
    function() { return getUserByEmail(usernameOrEmail) } 
)
.then( function(user) { return checkPassword(user, password) } )
.done( 
    function() { console.log('success'); }, 
    function(err) { console.log('failure', err) }
);

したがって、このコードは機能しますが、これを行うためのよりエレガントな方法があるはずです (私のコードはハックのように見えると思います)。

4

1 に答える 1

6

次のようなものはどうですか:

 getUserByUsername(usernameOrEmail).
 catch(getUserByEmail.bind(null, usernameOrEmail)).
 then(function(user){
     if(!isValidPassword(user, password)) throw new Error("Invalid Password");
 }).then(function(){
     // success
 }, function(){
    //fail
 });

重要事項:

  • throw約束を拒否し、return連鎖を続けることができます。promise コンストラクターはほとんど使用されません。
  • の最初のパラメーターを省略することもできます.thenが、そのエイリアスである.then(null, function(){...ほうが簡単に使用できます。.catchより一般的に.thenは、関数ではないパラメーターを無視します。
  • 拒否と戻り値は伝播します。拒否を処理しない場合.catch(または の 2 番目の引数.then) は、処理するまでチェーンを移動するだけです。同じことが戻り値にも当てはまります。これが、最初の 2 行が次の内容を含んでいる理由です。
    • ユーザー名でユーザーを取得してみてください
    • うまくいかない場合は、メールで試してみてください。

一般的に、あなたが説明することは、約束と非常によく似ており、同期コードの例外に非常によく似ています。この種のことを効果的に行う方法を学ぶことが重要です。

于 2014-07-30T18:34:08.220 に答える