简体   繁体   中英

return a value in an event handler function

I'm absolutely out of idea now and i would like anyone with better idea to help give a concise solution to this. here is my code:

Ok what I'm trying to write here is a program that listen to the load event for fetching data from an api and save it in cache, then clear the cache when the user try to exit the browser. using the opt parameter to set when to load and unload the cache outside the method.

class myc {
  // ... 
  async get(url, opt = {}) {
    let js, er, data;
    if (opt.load === true) {
      window.addEventListener('load', getData);
    }
    if (opt.unload === true) {
      window.addEventListener('beforeunload', removeData);
    }
    async function getData() {
      try {
        let r = await fetch(url) 
        if (!r.ok) {
          throw new Error(r.statusText)
        } else {
          js = await r.json();
        }
      } catch(e) {
        er = e.message;
      }
      if (js) {
        localStorage.setItem(key, js);
        data = localStorage.getItem(key);
      }
      // Main problem here (*)
      return {
        data : data ? data : null,
        error: er
      };
    }
    function removeData(){
      localSorage.clear();
    }
    let res = await getData();
    window.removeEventListener('load', getData);
    window.removeEventListener('beforeunload, removeData);
    return res;
  }
}

The line with (*) is the main problem here. So how do i return the required value from that function to then be used in another instance

The short answer: you don't.

Even if you returned a value from an event handler, it would have nowhere to go because you don't have access to the thing that actually called the event handler to be able to grab that return value.

Instead, you simply set the value somewhere in the scope you can grab it later.

Since you are in a class, you could simply set it to this.myValue and then grab it with the same.

The only gotcha with that is you have to make sure your event handler is bound to the proper scope.

You can do that one of two ways. On this line:

window.addEventListener('load', getData);

you can bind getData so it looks like this:

window.addEventListener('load', getData.bind(this));

That way the this inside of getData will refer to your class.

Alternatively, you could switch this line:

async function getData() {

to an arrow function syntax:

const getData = async () => {

which will automatically bind to the current context.

Simply use a global variable that you update in the event handler.

Using a call back function (or simply calling another function with the "return" variable value as parameter) to do some more processing is another way of achieving what you probably want.

Example:

async function getData(){
    //event handler doing it's task
    //create { data : data ? data : null, error: er } as global var
    var returnData = { data : data ? data : null, error: er };
    //or
    functionToDoMoreProcessing({ data : data ? data : null, error: er });
}

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