【问题标题】:How to make a Promise not re-run code when already resolved?已解决时如何使 Promise 不重新运行代码?
【发布时间】:2016-12-25 02:54:42
【问题描述】:

我有一个用户模型:

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() 函数到那个返回一个承诺的类。

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

【问题讨论】:

标签: javascript typescript promise


【解决方案1】:

在您的情况下,loadProfile 将再次执行内部代码。为避免这种情况,您需要将承诺存储在某个变量中。例如(es6,因为我不太了解 typescript):

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

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

【讨论】:

  • 还值得注意的是,promise 解析的任何数据都将传递给稍后添加的任何.then,Promises 不能“重新解析”,但可以链接到已经解析的承诺。
  • 这不会阻止他多次调用user.loadProfile()
  • 谢谢。这个概念也适用于 Typescript。干杯。
【解决方案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()中的代码会立即执行。

【讨论】:

    猜你喜欢
    • 2021-04-15
    • 1970-01-01
    • 2021-10-18
    • 2022-10-20
    • 2023-04-06
    • 2020-11-03
    • 2021-01-21
    • 2014-12-25
    • 1970-01-01
    相关资源
    最近更新 更多