Home pass object reference into javascript async function, but the unexpected value gotten
Reply: 3

pass object reference into javascript async function, but the unexpected value gotten

Yu Fang
1#
Yu Fang Published in 2018-02-13 11:15:02Z

I use the object as the function parameter to try saving out the value of the consequence of a async function. Code snippets shown bellow,

function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms));}
...

let u={};
async function exec(){
     getCurrUser(action.w,u);//get current user login data from indexeddb io
     await sleep(2000);
};
exec().then(()=>{console.log(u); /*u is still {}, but WHY ?*/ });   });

getCurrentUser is something like

export function getCurrUser(window,user) {
   ...
 _req.onsuccess=function(event){
                let cursor=event.target.result;
                //confirm in this line that user object does has some value
                if(cursor) {user = Object.assign({}, cursor);return;}
                else {return;}
            };
  ...

}

My understanding is that if the timeout is long enough to secure the valid execution of getCurrUser, I can get the final function output through the 2nd paramter reference. But the fact is not so. Why? Any ideas are welcome.

T.J. Crowder
2#
T.J. Crowder Reply to 2018-02-13 11:30:16Z

When you assign to user in the callback in getCurrUser, all you're doing is assigning to the parameter (making it refer to a newly-created object); that parameter has no link whatsoever to the u variable you passed into getCurrUser.

When you do:

getCurrUser(action.w,u);

...you're reading the current value of u and passing that value into getCurrUser as user. Assigning a new value to user has no effect on u at all. The value, not the variable, was passed.

While you could solve this in this specific case by doing what TKoL shows, I would make getCurrUser return a promise instead, and consume the promise rather than relying on writing to pre-created objects, making exec close over u, etc.:

function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms));}

async function exec(){
     const u = await getCurrUser(action.w); //get current user login data from indexeddb io
     await sleep(2000);
     return u;
};

exec()
    .then(u => {
        console.log(u);
    })
    .catch(e => {
        // deal with the error -- you MUST always either handle
        // rejections or return the promise chain to something that will
    });

export function getCurrUser(window) {
    return new Promise((resolve, reject) => {
        // ...
        _req.onsuccess = function(event) {
            let cursor = event.target.result;
            //confirm in this line that user object does has some value
            if (cursor) {
                 resolve(Object.assign({}, cursor);
            } else {
                 reject(new Error(/*...*/));
            }
        };
    });
};
TKoL
3#
TKoL Reply to 2018-02-13 11:26:16Z

When you do user = Object.assign({}, cursor);, you are NOT changing the 'u' variable, you are reassigning the 'user' variable.

Try Object.assign(user, cursor) -- this should modify the u variable object u refers to.

Quentin
4#
Quentin Reply to 2018-02-13 11:19:44Z

user = Object... overwrites the value of the user variable.

This throws away the reference to the object that is created here — let u={}; — and later assigned to user.

The u variable continues to point to the original object.

You would need to modify the existing object and not overwrite the value of user with a new one in order to achieve what you want with your current approach.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.371096 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO