Home > Net >  How to return a closure from an async function?
How to return a closure from an async function?

Time:01-17

I'm trying to return a function (closure) from a async function. So far, the way I have things space is always a promise and not a function, even though it should be a closure.

// ...
    const [space, set_space] = React.useState(false);
    React.useEffect(
    () => {
        API.SERVER(query, PAGE_SIZE)
        .then(response => set_space(response));
    },
    [query]
    );

    React.useEffect(
    () => {
        console.log(space.constructor);
        if (space) {
        space(page)
            .then(response => set_titles(Array.from(response.data)));
        }
    },
    [space, page]
    );
// ...

API

// ...
export default {
    SERVER:async function(search, width)
    {
        if (!search) {
        // return () => {};
        search = DEFAULT_QUERY;
    }
    const all = (await axios.get(SEARCH_URL   `?search=${search}`)).data;
    console.log(all);
    const pages = chunk(all, width);
    // function pager(results) {
    //     const dex = (results > width ? results / width : 0);
    //     const next = pages[dex];
    //     return axios.get(SEARCH_URL   `?fromids=${next}`);
    // }
    // return pager;
    return function(results) {
        const dex = (results > width ? results / width : 0);
        const next = pages[dex];
        return axios.get(SEARCH_URL   `?fromids=${next}`);
    };
    // return pager;
}
};

space.constructor says it's a Promise, but it should be a function that returns axios' Promise, not a Promise it's self. I can't really change the way the API is set up because I need to hold the index client side, then walk though it by changing space's parameter.

CodePudding user response:

The problem is, that set_space doesn't handle functions the same way as other values.

That's because React's state setters can take a callback that receives the previous state as an argument.

However, React has no way of differentiating between a callback and a value that happens to be a function. So, React will assume it's a callback and calls it, then set the state to contain its return value, another Promise.

To put the function itself into the state, you can create a callback that returns the function, like this:

API.SERVER(query, PAGE_SIZE)
.then(response => set_space(() => response));

CodePudding user response:

Hmmm... you just want a function that on call returns you the promise? What about useCallback then?

const triggerAsync = React.useCallback(
    () => {
        return API.SERVER(query, PAGE_SIZE)
        .then(response => set_space(response))
    },
    [query]
    );

triggerAsync should then return a promise when you execute it

  •  Tags:  
  • Related