2017-03-28 13 views
0

でキャッチ使用しているとき、私は(バベルとのWebPACKでtranspiled)このようなJSON-RPCプロバイダを持っている:

export default function() { 
    var id = 1; 
    function request(method, params) { 
     return JSON.stringify({ 
      id: id++, 
      method: method, 
      params: params || [] 
     }); 
    } 
    var uri; 
    this.setup = function(user_uri) { 
     uri = user_uri; 
    }; 
    this.$get = ['$http', '$q', function($http, $q) { 
     function rpc(method, params) { 
      return $http({ 
       method: 'POST', 
       url: uri, 
       data: request(method, params) 
      }).then(response => response.data); 
     } 
     var defer = $q.defer(); 
     rpc('system.describe').then(data => { 
      var service = {}; 
      data.result.procs.forEach(spec => { 
       service[spec.name] = function(...args) { 
        var defer = $q.defer(); 
        if (args.length == spec.params.length) { 
         return rpc(spec.name, args).then(data => { 
          if (data.error) { 
           defer.reject(data.error); 
          } else { 
           defer.resolve(data.result); 
          } 
         }); 
        } else { 
         defer.reject('Invalid arity expected ' + 
            spec.params.length + 
            ' got ' + 
            args.length); 
        } 
        return defer.promise; 
       }; 
      }); 
      defer.resolve(service); 
     }); 
     return defer.promise; 
    }]; 
}; 

と私は1つの関数を呼び出す:

 service.login('user', 'password').then(function(token) { 
      if (token) { 
       localStorage.setItem('notes_token', token); 
       localStorage.setItem('notes_username', 'user'); 
      } 
      console.log('token: ' + token); 
     }).catch(function(error) { 
      console.log(error); 
     }); 

要求がエラーを返すと私はコンソールでこれを持っています:

トークン:未定義 [エラー]おそらく未処理の拒否:使用r非アクティブ

なぜ私はcatchからconsole.logを取得せず、thenを実行しましたか?

私も試してみた:

 service.login('user', 'password').then(function(token) { 
      if (token) { 
       localStorage.setItem('notes_token', token); 
       localStorage.setItem('notes_username', 'user'); 
      } 
      console.log('token: ' + token); 
     }, function(error) { 
      console.log(error); 
     }); 

と同じ結果を得ます。私は角度1.6.3を使用しています。

+1

は[繰延アンチパターン](http://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-を避けるために使用したいと思うでしょうどのように回避するか)! – Bergi

答えて

0

deferred antipatternを避けてください! $q.defer()を絶対に使用しないでください。あなたの関数が結果の約束を拒否したときは、それを無視しているだけです - unhandled rejectionです。

あなたは

this.$get = ['$http', '$q', function($http, $q) { 
    function rpc(method, params) { 
     return $http({ 
      method: 'POST', 
      url: uri, 
      data: request(method, params) 
     }).then(response => response.data); 
    } 
    return rpc('system.describe').then(data => { 
// ^^^^^^ 
     var service = {}; 
     for (const spec of data.result.procs) { 
      service[spec.name] = function(...args) { 
       if (args.length == spec.params.length) { 
        return rpc(spec.name, args).then(data => { 
         if (data.error) { 
          throw data.error; 
//       ^^^^^ 
         } else { 
          return data.result; 
//       ^^^^^^ 
         } 
        }); 
       } else { 
        return $q.reject('Invalid arity expected ' + 
//     ^^^^^^^^^^^^^^^^ 
           spec.params.length + 
           ' got ' + 
           args.length); 
       } 
      }; 
     } 
     return service; 
//  ^^^^^^ 
    }); 
}]; 
+0

"$ q.defer()を使わないでください" - これは分かりません。 $ q.deferは広く使われています。 –

+0

最低レベルでのみ使用してください。非同期関数を呼び出す場合、 '$ q.defer'は必要ありません。関数は約束を返します。変更できない関数の場合にのみ、遅延を使用するラッパーを記述する必要があります。そして、 '$ q.defer'の多くの使い方は間違っています。 – Bergi

関連する問題