如何使Promise在已经解决后不重新运行代码?

时间:2016-08-18 08:49:27

标签: javascript typescript promise

我有一个用户模型:

export class User extends Serializable{
  id: string; 
  first_name: string; 
  middle_name: string; 
  last_name: string;
  email: string;
  image_url: string;

  // mykeyStore
  static store:StoreDatabase = new StoreDatabase("mykeyStore");


... More code...

和该类的loadProfile()函数返回一个promise。

loadProfile():Dexie.Promise<any>{
    let promise = User.store.get('user')
      .then(
        tuple => {
          // Extract User Data from tuple
          let user_data = tuple && tuple.value

          // Fill User attribute for Tuple's value
          for (var attr in user_data) {
            this[attr] = user_data[attr];
          }
        }); 

    return promise;
}

如何构建我的代码,以便通过调用以下内容调用loadProfile并不总是运行then(如果已经解决):

let user = new User();
user.loadProfile().then( () =>
   console.log(user.first_name)
);

2 个答案:

答案 0 :(得分:3)

在您的情况下,loadProfile将再次执行内部代码。为避免这种情况,您需要将promise存储在某个变量中。例如(es6,因为我不太熟悉打字稿):

// Execute code inside loadProfile and store the promise in some variable
const loadProfilePromise = user.loadProfile();

// Will show Hurray
loadProfilePromise.then(() => console.log('Hurray');

// Will not execute code inside loadProfile again, but will show 'Hurray2'
setTimeout(() => {
    loadProfilePromise.then(() => {
        console.log('Hurray2'));
    });
}, 100);

另外,不要忘记在promises中处理异常和拒绝,并记录它们; D

答案 1 :(得分:2)

每次拨打user.loadProfile()时,都会创建一个新的承诺。因此,.then()中的代码将始终运行。

如果您想避免多次加载属性,可以将功能更改为:

loadProfile():Dexie.Promise<any>{
    if (this.promise) return this.promise
    this.promise = User.store.get('user')
      .then(
        tuple => {
          // Extract User Data from tuple
          let user_data = tuple && tuple.value

          // Fill User attribute for Tuple's value
          for (var attr in user_data) {
            this[attr] = user_data[attr];
          }
        }); 

    return this.promise;
}

然后,如果您在user.loadProfile()已加载时调用,.then()中的代码将立即执行。