简体   繁体   中英

Lazy loading with promise and closure scope

I have a need to make async and lazy loading module to fetch some config values. Is there some limitation with closure variable scoping in relation to promises?

Given the following module that defines a loader function that performs the async loading with promises and stores the config to module scope in order to implement lazy loading and thus avoid loading the config unnecessary each time.

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

With the following client code, the config is loaded but always freshly, ie it is not cached, lazy-loading not working.

const cc = configModule();

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

Is there something I'm missing with closure scopes and promises here? Or is this approach even feasible? What is the alternative?

Your caching module is working right. But in your test you're making both "API calls" immediately. So both cc() calls will test if (!config) before the other one updated it. As soon as one call is able to return with a value and update the config , the cache will start working.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM