Best way to wait for 3rd-party JS library to finis

2019-07-13 20:16发布

问题:

I'm wrapping a 3rd-party JS library in an Angular service. How can I guarantee that the 3rd-party JS library is loaded/initialized/etc. before using my service?

Can you take a look at the following code and tell me if this is a good coding practice? I'm setting up a promise in the service's constructor (promise that will eventually be fulfilled) and I have the service methods depend on the success of that promise (see getMessages).

@Injectable()
export class GmailService {

  private _readyPromise;

  // Load Gmail API client library.
  // gapi.client.load() returns a promise.
  constructor() {
    this._readyPromise = gapi.client.load('gmail', 'v1');
  }

  private ready():Promise {
    return this._readyPromise;
  }

  // Return Gmail messages for the current user.
  getMessages() {
    return this.ready().then(() => {
      return gapi.client.gmail.users.messages.list({
        'userId': 'me'
      }).then(resp => console.log(resp));
    });
  }
}

In that exemple, I'm using the Gmail API for JavaScript and it turns out that gapi.client.load() already returns a promise, which simplifies the code. In a different scenario I could have created my own promise and fulfilled it manually when a specific condition is met.

回答1:

Your approach seems fine! Another one would be to bootstrap your application after your Gmail API library is loaded:

var app = platform(BROWSER_PROVIDERS)
   .application([BROWSER_APP_PROVIDERS, appProviders]);

gapi.client.load('gmail', 'v1').then(() => {
  return app.bootstrap(AppComponent);
});

This way you will be sure that the library is ready when using it within your application.

Here is a corresponding plunkr describing the global approach: https://plnkr.co/edit/ooMNzEw2ptWrumwAX5zP?p=preview.