首页 > 解决方案 > 带有承诺和闭包范围的延迟加载

问题描述

我需要制作异步和延迟加载模块来获取一些配置值。与 Promise 相关的闭包变量范围是否存在一些限制?

给定以下模块,该模块定义了一个加载器函数,该函数使用承诺执行异步加载并将配置存储到模块范围,以实现延迟加载,从而避免每次加载不必要的配置。

const configModule = () => {
  let config;

  const loader = () => {
    return new Promise((resolve, reject) => {
      if(!config) {
        setTimeout(() => {
          const loadedValues = {foo: 'this be config', bar: 'OK?'};
          console.log('config loaded', loadedValues);
          resolve(loadedValues);
        }, 1);  
      }
      else {
        console.log('config already loaded');
        resolve(config);
      }
    }).then(res => {
      console.log('loader then', res);
      config = res;
      return config;
    })
  };

  return {
    loader: loader
  };
};

使用下面的客户端代码,配置被加载但总是新鲜的,即它没有被缓存,延迟加载不起作用。

const cc = configModule();

cc.loader().then(result => {
  console.log('1', result);
});
cc.loader().then(result => {
  console.log('2', result);
});

这里的闭包范围和承诺是否缺少我的东西?或者这种方法是否可行?什么是替代方案?

标签: javascriptpromiseclosureslazy-loading

解决方案


您的缓存模块工作正常。但是在您的测试中,您会立即进行两个“API 调用”。因此,两个 cc() 调用都将if (!config)在另一个调用更新之前进行测试。一旦一个调用能够返回一个值并更新config,缓存将开始工作。

const configModule = () => {
  let config;

  const loader = () => {
    return new Promise((resolve, reject) => {
      if (!config) {
        setTimeout(() => {
          const loadedValues = {
            foo: 'this be config',
            bar: 'OK?'
          };
          console.log('config loaded', loadedValues);
          resolve(loadedValues);
        }, 1);
      } else {
        console.log('config already loaded');
        resolve(config);
      }
    }).then(res => {
      console.log('loader then', res);
      config = res;
      return config;
    })
  };

  return {
    loader: loader
  };
};

const cc = configModule();

cc.loader().then(result => {
  console.log('1', result);
});
setTimeout(() => cc.loader().then(result => {
  console.log('2', result);
}), 100);


推荐阅读