SendResponse fails when using a Promise

2019-07-03 22:32发布

问题:

In the extension I am building, on click of a button, a request is sent from ChromeUtils.js

 return new Promise(function(fulfill,reject){
            var request = {
                type : "background.twitterRequestToken",
            };
            chrome.runtime.sendMessage(request, function(response) {

                if (response)
                {
                    fulfill(response);
                }
                else
                {
                    reject(response);
                }
            });
        });

to the background.js which in turn calls an oauth Api to send a request to the remote server.

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {

    console.log("background.js: " + JSON.stringify(request));

    var type = request.type;


    if (type == "background.twitterRequestToken")
    {
        oauth.authorize().then(function(token,secret,userId,screenname){
            console.log("Sending Response on Authorize");
            sendResponse({success:true,userId:userId,screenName:screenname});
        });
        console.log("Before Return true");
        return true;
    }

I am using the oauth scripts from the example given at https://developer.chrome.com/extensions/tut_oauth but due to a requirement have modified the oauth to use promise. When implemented as a promise, the sendResponse fails but when using the default implementation using callbacks. the sendResponse goes through.

Default implementation using callbacks:

if (type == "background.twitterRequestToken")
    {
        oauth.authorize(function(token,secret,userId,screenname){
            console.log("Sending Response on Authorize");
            sendResponse({success:true,userId:userId,screenName:screenname});
        });
        console.log("Before Return true");
        return true;
    }

Error message in the background console when implemented as a promise is

Uncaught (in promise) Error: Attempting to use a disconnected port object

The reason I want to use a promise is that when sending signedRequests using Oauth, I want to include part of the xhr response in the sendResponse, e.g. as shown below.

if (type == "background.tweet")
{
    var status = request.tweet.text;
    var url = "https://api.twitter.com/1.1/statuses/update.json";
    var request = {
        'method':'POST',
        'parameters': {
            'status':status
        }
    }

    oauth.sendSignedRequest(url,request).then(signedRequestCallback).then(function(resp,xhr){
        console.log("signedRequestCallback success");
        console.log("Sending response");
        sendResponse({success:true,status_id:resp.id});
    });

    return true;

}

I have already included return true in my code and as I explained it works fine when not using Promise. It fails when using Promise because the of the error message I included.

===============Update========

To repro this I created a simpler example but I do not face the issue there when I use a Promise. So this may not have anything to do with Promise.