#function returning promise returns promise before promise is complete

70 messages · Page 1 of 1 (latest)

livid totem
#

so i did post something about this a while ago but now ive cut down a lot on the amount of promises and now im only using them in 1 function which should create and wait for any of the events that creating a connection to the indexed db should make

async openDB() {
    const open_db_req = indexedDB.open(this.name, this.version);
    await this.openDBPromise(open_db_req);
    console.log("tabls created");
}

openDBPromise(request): Promise<void> {
    return new Promise((resolve, reject) => {
        console.log("starting listener promise");
        request.onsuccess = (e) => {
            console.log("on success");
            // create all the objects that represent all the tables in the database with a for loop
            // the table objects will set themselves up in their own class
            resolve();
        };

        request.onerror = (e) => {
            console.log("on error");
            console.error("open IDB error: ", e);
            reject();
        };

        request.onupgradeneeded = (e) => {
            // actually create all the database stuff that needs to be created
            resolve();
        };
    });
}

also need to show what is calling this at the top level

databases.loadSchemas();

console.log("databases:");
console.log(databases);
console.log(JSON.stringify(databases.databases));
console.log(databases.databases.length);
#

so the problem is that it prints the console logs in this order

starting listener promise
databases:
Object { databases: (2) […] }
(very long text returned by json.stringify but the important thing about it is that the tables array is empty when it should have been filled by the code in the onsuccess listener)
2
on success

but the on success should come before databases:

steel plank
#

Functions that return promises will return before the promise is resolved. This is basically the point of promises. If you want something to happen after the a promise resolves, you can call .then with a callback, or, inside an async function, await it. I don't know what your databases.loadSchemas is but it might need to become a promise returning function itself, easiest way is to make it async.

livid totem
#

!helper

strange dagger
#

where are you calling openDB?

livid totem
#
async loadSchemas() {
    console.log(`schemas file: ${SchemasFile}`);
    SchemasFile.forEach((schema) => {
        switch (true) {
            case /IndexedDB/.test(schema.type): {
                console.log("indexeddb found");
                const newIDB = new EmbeddedDB(schema);
                newIDB.openDB();
                this.databases.push(newIDB);
            }
        }
    });
}
strange dagger
#

ah yeah i shouldve known

#

god that switch is horrible

#

anyways

livid totem
#

planning to add more later

strange dagger
#

doesn't matter, it's horrible

#

anyways, the openDB call isn't awaited there

#

and even if it were awaited here, the loadSchemas call isn't awaited

#

if you want to wait for a promise to be completed, you have to await it all the way up through async methods, because async methods are also promises

livid totem
strange dagger
#

although, you can't properly await it with a forEach.
depending on if you want it to be concurrent or linear, you can use a map with Promise.all or a normal for or for..of loop

strange dagger
#

don't bother with the forEach, you won't be able to await anything inside it properly

livid totem
strange dagger
#

for..of, not for..in

#

for..in is for object keys, for..of is for iterables

#

and please just change your switch to a normal if

livid totem
#

oh nice good to know works better now, i like switches idc itll look better later

new problem is that it doesnt wait for the indexed db object

basically open_db_request is passed to openDBpromise as request where in the onsuccess listener it does request.result which doent return anything apparently

#

basically this

#

should be this

#

@strange dagger

strange dagger
#

itll look better later
it won't

strange dagger
livid totem
#

it should be assigning that value in the onsuccess listener so ye its at the same layer

strange dagger
#

that doesn't answer my question

#

is loadSchemas being awaited

livid totem
#

yes

#

ikts being awaited all the way to the promise where it assigns this value

strange dagger
#

can you show the code that you have at the top level again

livid totem
#

top

await databases.loadSchemas();

console.log("databases:");
console.log(databases);
console.log(JSON.stringify(databases.databases));
console.log(databases.databases.length);

mid

async loadSchemas() {
    console.log(`schemas file: ${SchemasFile}`);
    for (var schema of SchemasFile) {
        switch (true) {
            case /IndexedDB/.test(schema.type): {
                console.log("indexeddb found");
                const newIDB = new EmbeddedDB(schema);
                await newIDB.openDB();
                this.databases.push(newIDB);
            }
        }
    }
}
strange dagger
#

maybe debug/console.log some stuff inside the promise body to check if it's maybe just not getting the data to assign?

livid totem
#

oh... i see

#

those last 2 {} are in

#

so the IDB isnt created for a while uuuh

strange dagger
#

that's being handled synchronously, i'd think that shoud work

livid totem
#

but i need to wait for that as well

#

when it is returned at the top level db shouldnt be empty

strange dagger
#

weird that JSON.stringify(request) and JSON.stringify(request.result) are giving the same empty object though

#

oh maybe they're functions?

#

try console.log(request) normally

livid totem
#

what the final object is vs what it is when its needed

strange dagger
#

request.result is a IDBDatabase, maybe it's just not showing in the json-encoded string?

#

since it's being reduced to {} here too

#

maybe expand the result out to check if IDBDatabase is populated

livid totem
#

ye it knows the types, im using json.stringify that should get all the stuff out in that momemt

strange dagger
#

don't stringify them at all

#

just log them normally and expand the result

#

when you log objects in the browser console you can expand them

livid totem
#

what u mean this, doest this get updated after the object has been logged

strange dagger
#

yes

#

does that look like the data you're expecting

livid totem
#

well idk what an IDB object is supposed to look like but if thhats it then thats what i want i need to have those function available immediately when its returned tot he top layer

strange dagger
#

i think they probably are, just that they aren't being shown in the json-encoded log

livid totem
#

its empty at the top layer, i can try running some functions on it that should be there

strange dagger
#

if it wasn't empty, would it show data from JSON.stringify?

livid totem
#

no idea i assume it always returns the full representation on an object no matter what it is right so if its empty then it must have nothing in it

strange dagger
#

no, json omits stuff it can't represent

#

that's why i'm urging you to use the full logs instead of just the json parts

livid totem
#

why would it omit name: "password_manager", version: 2,

#

its a string and an int why wouldnt it be able to represent that

#

how can i print it out another way where it wont update, u want me to put the log in verbose mode

strange dagger