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

How to consume a Promise from a service (native script / firebase)?

我有一个 userService 调用 firebase.login(),其中 returns 是 Promise<User> 类型的结果。它是这样称呼的:

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

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

这是怎么做到的?另一个组件如何对此做出反应?

上面提到的组件是一个名为LoginPage的class。它有一个 Login 按钮,可以启动 Firebase 登录。该按钮链接到 LoginPage class.

中的函数(也称为 login()

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; 
    });
 }

UserService login 方法应该 return 承诺使其可用于链接:

  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 如果有未捕获的 promise 将抛出错误):

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

它总是优于 return 承诺,至少对于测试目的而言。