如何从服务(本机脚本/ firebase)中使用Promise?

时间:2016-08-31 13:57:28

标签: javascript angular firebase promise nativescript

我有userService,调用firebase.login(),返回类型为Promise<User>的结果。它被称为:

firebase.login( { config... 
})
.then (function (result) { /* use result */}, 
       function (error)  { /* use error */ });

在项目的其他地方,在UI组件中,我需要对登录的结果做出反应(即成功或错误)。我不想将任何路由或类似逻辑放入用户服务中,而是让其他组件控制接下来会发生什么。

怎么做的?另一个组件如何应对它?

上面提到的组件是一个名为LoginPage的类。它有一个Login按钮,可以启动Firebase登录。该按钮链接到login()类中的函数(也称为LoginPage)。

XML:

<Button [text]="Sign in" class="submit-button" (tap)="login()"></Button>

login.component.ts

login() {
   this._userService.login(this.user)
   .then(function (data) {
      /* go to next screen */
    });
}

上述内容显然是错误的,因为无论登录成功与否,then子句将始终执行。

以下是userService中的登录功能:

@Injectable()
export class UserService {


  login(user: User) {

    firebase.login({
      type: firebase.LoginType.PASSWORD,
      email: user.email,
      password: user.password
    })
    .then( function (result) {
       console.log("Successful Login! " + JSON.stringify(result));
       return result;
     }, function (error) {
       console.log(error);
       return error; 
    });
 }

1 个答案:

答案 0 :(得分:2)

UserService login方法应该返回一个承诺,使其可用于链接:

  login(user: User) {
    return firebase.login(...)...
  }

在上面的原始版本中,登录错误已经被捕获,这会留下具有分辨率的承诺,可能是结果或错误。

此处处理错误的首选方法是不捕获服务本身的错误。我们总是想知道登录请求是否成功。

  login(user: User) {

    return firebase.login(...)
    // second callback is optional if we don't need to log errors
    .then( function (result) { ... }, function (error) {
       console.log(error);
       return firebase.Promise.reject(error); 
    });
  }

这样一种错误可以(并且如果有未捕获的承诺,Angular 2也会抛出错误)被捕获并处理:

login() {
   return this._userService.login(this.user)
   .then(function (data) {
      /* go to next screen */
   })
   .catch(function (error) { ... });
}

至少出于测试目的,最好返回承诺。