如何在构造函数中等待Promise

时间:2019-06-28 11:10:35

标签: javascript angular typescript

我有Angular Service,它发出一些http请求,但是我需要从Promise获取这些请求的标头。现在,它是如何工作的,我将我的诺言转换为可观察

export class SomeService {
  constructor(private http: HttpClient, private auth: AuthenticationService) {}

  getInfo(id: string): Observable<any> {
    return this.auth.getToken().pipe(mergeMap((token: any) => { 
      let httpOptions = {
        headers: new HttpHeaders({
          'Content-Type':  'application/json',
          'Authorization': 'Bearer ' + token
         })
        }
        return this.http.get(`${this.serverURL}/info`, httpOptions);
    }))
  }
}



getToken() {
   return from(this.storage.get(TOKEN_KEY));
}

但是显然我有20-50个请求,并且每个请求都获取auth令牌并不是很好。 我想一次获取令牌并将其用于所有请求。另外,我还有其他来自Promise的标头,需要在我的请求中使用。那么,在这种情况下,如何才能一次获取异步标头(可能在构造函数中)?

4 个答案:

答案 0 :(得分:1)

首先考虑是否确实需要优化此代码。性能优化通常仅在经常运行的部分代码中有用。当您说您执行20到50个请求时,听起来好像使用不了很多(应用程序的其他部分可能要占用更多的CPU)。

话虽这么说:如果您仍然想解决这个问题,您确实可以在构造函数中获取令牌。

@extends('person.person-dashboard')
@section('personContent')

    <div class="page-body">
        <div class="row">
            <div class="col-lg-12">
                <div class="row-no-margin">
                    <br>
                    @if ($message = Session::get('successRemove'))
                        <div class="alert alert-success alert-block">
                            <button type="button" class="close" data-dismiss="alert">×</button>
                            <strong>{{ $message }}</strong>
                        </div>
                    @elseif($message = Session::get('failRemove'))
                        <div class="alert alert-danger alert-block">
                            <button type="button" class="close" data-dismiss="alert">×</button>
                            <strong>{{ $message }}</strong>
                        </div>
                    @elseif($message = Session::get('defaultRemoveError'))
                        <div class="alert alert-danger alert-block">
                            <button type="button" class="close" data-dismiss="alert">×</button>
                            <strong>{{ $message }}</strong>
                        </div>
                    @endif
                </div>
                <div class="cover-profile">
                    <div class="profile-bg-img">
                        <img class="profile-bg-img img-fluid" src="/files/assets/images/bg-img1-30opacity.png"
                             alt="bg-img">
                        <div class="card-block user-info">
                            <div class="col-md-12">
                                <div class="media-left">
                                    <div class="card-block">
                                        <div class="img-hover">
                                            {{--Check if the picture is null, if so show default image--}}
                                            @if (is_null($person->avatar))
                                                <img class="img-fluid img-radius"
                                                     src="{{asset('storage/images/userImage/standard/default.png')}}"
                                                     width="150"
                                                     height="150" alt="user-img">
                                                <div class="img-overlay img-radius">
                                            <span>
                                                <a href="/person/profile/{{$person->person_id}}/{{$person->last_name}}/uploadfile"
                                                   class="btn btn-sm btn-primary">
                                                    <i class="icofont icofont-edit"></i></a>
                                            </span>
                                                    @else
                                                        <img class="img-fluid img-radius"
                                                             src="{{asset('storage/images/userImage/standard').'/'.$person->avatar}}"
                                                             width="150"
                                                             height="150" alt="user-img">
                                                        <div class="img-overlay img-radius">
                                            <span>
                                                <a href="/person/profile/{{$person->person_id}}/{{$person->last_name}}/uploadfile"
                                                   class="btn btn-sm btn-primary">
                                                    <i class="icofont icofont-edit"></i></a>
                                                <a href="/person/profile/{{$person->person_id}}/{{$person->last_name}}/remove"
                                                   class="tabledit-delete-button btn btn-sm btn-danger waves-effect waves-light active"
                                                   name="delete-image" id="delete-image-button"
                                                   onclick="return confirm(trans('collaborators.areYouSure'))">
                                                    <i class="icofont icofont-ui-delete"></i></a>
                                            </span>
                                                            @endif
                                                        </div>
                                                </div>
                                        </div>
                                    </div>
                                    <div class="media-body row">
                                        <div class="col-lg-12">
                                            <div class="user-title">
                                                @if ($person->person_title == null)
                                                    <h2>{{$person->first_name}} {{$person->last_name}}</h2>
                                                @else
                                                    <h2>{{$person->person_title->name}} {{$person->first_name}} {{$person->last_name}}</h2>
                                                @endif
                                                <span>{{$person->mobile}}, {{$person->email}}</span>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-lg-12">
                    <div class="cover-profile">
                        <div class="profile-bg-img">
                        </div>
                        <div class="card-block user-info">
                            <div class="col-md-12">
                                <div class="media-body row">
                                    <div class="col-lg-12">
                                        <div class="user-title">
                                        </div>
                                    </div>
                                    <div>
                                        <div class="pull-right cover-btn">
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-lg-12">
                <div class="tab-header card">
                    <ul class="nav nav-tabs md-tabs tab-timeline" role="tablist" id="mytab">
                        <li class="nav-item">
                            <a class="nav-link active" data-toggle="tab" href="#personal" role="tab"
                               aria-expanded="true">{{trans('navigation.general')}}</a>

                            <div class="slide"></div>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" data-toggle="tab" href="#practitioner" role="tab"
                               aria-expanded="false">{{trans('navigation.practitioner')}}</a>

                            <div class="slide"></div>
                        </li>
                        @isset($practitioner->practitioner_id)
                            <li class="nav-item">
                                <a class="nav-link" data-toggle="tab" href="#availability" role="tab"
                                   aria-expanded="false">{{trans('navigation.availability')}}</a>

                                <div class="slide"></div>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" data-toggle="tab" href="#absence" role="tab"
                                   aria-expanded="false">{{trans('navigation.absence')}}</a>

                                <div class="slide"></div>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" data-toggle="tab" href="#contract" role="tab"
                                   aria-expanded="false">{{trans('navigation.contract')}}</a>

                                <div class="slide"></div>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" data-toggle="tab" href="#training" role="tab"
                                   aria-expanded="false">{{trans('navigation.training')}}</a>

                                <div class="slide"></div>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" data-toggle="tab" href="#history" role="tab"
                                   aria-expanded="false">{{trans('navigation.history')}}</a>

                                <div class="slide"></div>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" data-toggle="tab" href="#access" role="tab"
                                   aria-expanded="false">{{trans('navigation.access')}}</a>

                                <div class="slide"></div>
                            </li>
                        @endisset
                        @empty($practitioner->practitioner_id)
                            <li class="nav-item">
                                <a class="nav-link disabled" data-toggle="tab" href="#availability" role="tab"
                                   aria-expanded="false">{{trans('navigation.availability')}}</a>

                                <div class="slide"></div>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link disabled" data-toggle="tab" href="#absence" role="tab"
                                   aria-expanded="false">{{trans('navigation.absence')}}</a>

                                <div class="slide"></div>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link disabled" data-toggle="tab" href="#contract" role="tab"
                                   aria-expanded="false">{{trans('navigation.contract')}}</a>

                                <div class="slide"></div>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link disabled" data-toggle="tab" href="#training" role="tab"
                                   aria-expanded="false">{{trans('navigation.training')}}</a>

                                <div class="slide"></div>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link disabled" data-toggle="tab" href="#history" role="tab"
                                   aria-expanded="false">{{trans('navigation.history')}}</a>

                                <div class="slide"></div>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" data-toggle="tab" href="#access" role="tab"
                                   aria-expanded="false">{{trans('navigation.access')}}</a>

                                <div class="slide"></div>
                            </li>
                        @endempty
                    </ul>
                </div>
                <div class="tab-content">
                    <div class="tab-pane active" id="personal" role="tabpanel" aria-expanded="true">
                        <div class="card">
                            <div class="card-header">
                                <button id="edit-btn" type="button"
                                        class="btn btn-editpanel btn-sm btn-primary waves-effect waves-light f-right">
                                    <i class="icofont icofont-edit"></i>
                                </button>
                            </div>
                            <div class="card-block">
                                @include('person.profile.info-display')
                                @include('person.profile.info-edit')
                            </div>
                        </div>
                    </div>
                    <div class="tab-pane" id="practitioner" role="tabpanel" aria-expanded="true">
                        <div class="card">
                            @isset($practitioner->practitioner_id)
                            <div class="card-header">
                                <button id="edit-practitioner-btn" type="button"
                                        class="btn btn-editpanel btn-sm btn-primary waves-effect waves-light f-right">
                                    <i class="icofont icofont-edit"></i>
                                </button>
                            </div>
                            @endisset
                            <div class="card-block">
                                @include('person.profile.practitioner.practitioner-display')
                                @isset($practitioner->practitioner_id)
                                    @include('person.profile.practitioner.practitioner-edit')
                                @endisset
                            </div>
                        </div>
                    </div>
                    <div class="tab-pane" id="availability" role="tabpanel" aria-expanded="false">
                        <div class="row">
                            {{trans('navigation.availability')}}
                        </div>
                    </div>
                    <div class="tab-pane" id="contract" role="tabpanel" aria-expanded="false">
                        <div class="row">
                            {{trans('navigation.contract')}}
                        </div>
                    </div>
                    <div class="tab-pane" id="training" role="tabpanel" aria-expanded="false">
                        <div class="row">
                            @include('person.profile.training.training')
                        </div>
                    </div>
                    <div class="tab-pane" id="absence" role="tabpanel" aria-expanded="false">
                        <div class="row">
                            {{trans('navigation.absence')}}
                        </div>
                    </div>
                    <div class="tab-pane" id="history" role="tabpanel" aria-expanded="false">
                        <div class="row">
                            {{trans('navigation.history')}}
                        </div>
                    </div>
                    <div class="tab-pane" id="access" role="tabpanel" aria-expanded="false">
                        <div class="row">
                            {{trans('navigation.access')}}
                        </div>
                    </div>
                    <!-- tab content end -->
                </div>
            </div>
        </div>
        @include("settings.remove-confirmation")

        <link rel="stylesheet" type="text/css" href="/files/assets/css/custom-person-profile.css">
        <link rel="stylesheet" type="text/css" href="/files/assets/css/custom-j-forms.css">
        <script src="/files/js/views/person/person-profile.js"></script>
        <script src="/files/js/services/initialization.js"></script>
        <script src="/files/js/services/editButton.js"></script>
        <script src="/files/js/services/practitioner/editPractitionerButton.js"></script>
        <script src="/files/js/services/colors.js"></script>
        <script src="/files/js/modules/dataTable.js"></script>
        <script src="/files/js/modules/update.js"></script>
        <script src="/files/js/modules/create.js"></script>
        <script src="/files/js/modules/displayInfo.js"></script>
        <script src="/files/js/services/forms.js"></script>
        <script src="/files/js/services/validation.js"></script>
        <script src="/files/js/settings/setup-ajax-requests.js"></script>
@endsection

之所以可行,是因为您可以多次订阅相同的可观察对象。因此,我们仅对export class SomeService { // We store the observable here for later use private getTokenObservable: Observable<string>; constructor(private http: HttpClient, private auth: AuthenticationService) { // Retrieve the token now and store the observable this.getTokenObservable = getToken(); } getInfo(id: string): Observable<any> { // Zip the two observables together return zip( // Re use the previously stored observable this.getTokenObservable, // Also request the last login this.auth.getLastLogin() ).pipe(mergeMap((result) => { const token = result[0]; const lastLogin = result[1]; let httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token }) } return this.http.get(`${this.serverURL}/info`, httpOptions); })) } } getToken() { return from(this.storage.get(TOKEN_KEY)); } 的可观察对象进行一次请求并存储一次,然后在每次请求中重新使用它。

还要注意我们如何使用rxjs提供的zip运算符。这使我们可以将两个可观察变量合并在一起,从而可以在一个函数中处理两个可观察变量的结果。

答案 1 :(得分:0)

您可以编写用于获取令牌的单独服务,并且仅调用一次服务。下次需要令牌时,请检查服务变量中是否已具有令牌值,因此可以跳过http请求,只需将令牌返回给请求者即可。

答案 2 :(得分:0)

private _tokenObsevable = new BehaviorSubject<string>(null);
constructor(...) {
    this.auth.getToken().subscribe(token => this._tokenObservable.next(token))
}

getInfo(...) {
this._tokenObservable.pipe(
    switchMap(token => // rest the same
)

可选,您可以创建类似的吸气剂

get tokenObservable() {
    return this._tokenObservable.pipe(filter(val => !!val))
}

在这种情况下,您仅会获得非null值,而且如果令牌不会出现,则会陷入困境

答案 3 :(得分:0)

在这种情况下,您可以在文件中创建实用程序功能,然后将其导入您需要此令牌的任何位置,或者可以创建服务(如果此令牌来自服务器调用),然后可以将其注入所需的所有位置这个令牌。

此令牌也可以保存在const文件中,并在需要的位置导入。