I’m struggling to communicate with promises between scripts.
Once a runtime connection is established, I’m trying this in the background script and the equivalent in the content script, in attempt to establish a promise chain:
let id = p.sender.tab.id;
portFromCS[id].onMessage.addListener( message );
function message( o, p )
{
return new Promise( ( resolve, reject ) =>
{
resolve( { 'o' : o, 'p' : p } );
} ).then( ( b ) => { return f[b.o.func]( b.o.args, b.p ); } )
.then( ( r ) => { return r; } );
Also tried…
function message( o, p )
{
return new Promise( ( resolve, reject ) =>
{
f[o.func]( o.args, p ).then( (r) => { resolve( r ); }, ( e ) => { reject( e ); } );
} ); // close new promise
} // close message
function message( o, p )
{
return f[o.func]( o.args, p ).then( (r) => { return r; }, ( e ) => { return e; } );
} // close message
I haven’t added the rejection handlers in at this point.
The f[b.o.func]( b.o.args, b.p ) is invoking a function of the object f by string name and passing it the arguments sent in the postMessage and the sender data object. This part was working fine for a several weeks. It is the addition of the promise attempt that is causing the trouble.
There are no errors but when the content script posts the message in the background script to invoke the function of f, which is a promise itself, it doesn’t wait before processing the next then. The content script has the following (the rejection handlers have been removed to make code easier to read here).
DB.open_db( {} )
.then( ( ) => { return myPort.postMessage( { 'func' : 'send_data', 'args' : '' } ); } )
.then( (r) => { console.log(r); return unpack(r); } )
.then( (r) => { console.log(r); }, ( msg ) => { console.log( msg ); })
.then( ... );
I’m asking the content script to open the page’s indexedDB database and then post a message to the background script requesting the invocation of the send_data function, which is a promise.
The send_data function is invoked in the background script and complete successfully there, but the second then statement in the content script runs immediately, as if it returned with successful posting of the message rather than waiting for send_data to resolve or reject. So, r in the content script is always undefined.
For testing, I have been using a setTimeout in the send_data function in the background script of:
f.send_data = function( o, p )
{
return new Promise( ( resolve, reject ) =>
{
setTimeout( () => {
resolve( 'Test data retrieved successfully. Here it is!' );
}, 10000 );
} );// close new promise
}; // close send_data
Could you please tell me what it is that I’m doing wrong and not understanding? I was expecting to be able to add a few thens to the promise of send_data and have the background script wait for all of them to complete before sending a response back to the content script.
If I haven’t been clear, the specific problem I’m having is that I can’t get the content script’s promise chain to wait the ten seconds it takes for send_data to complete in the background script before processing the following then statement; or, more likely, I can’t get the background script to wait the ten seconds before it sends back a resolve to the postMessage.
Thank you.
I referenced these two documents to start:
and would like to know if and how they can be used with promises, as described in this document
provided by freaktechnikMartin Giger in response to this similar question How to make Promises work between background and foreground scripts?.