如何将js函数从异步调用转换为回调调用

时间:2014-03-23 16:30:48

标签: javascript google-chrome-extension

我正在尝试制作我的第一个Google Chrome扩展程序。此扩展必须拦截对mysite.com的请求并将用户重定向到其中一个站点镜像(例如mymirror.com)。从我的API服务器(例如api.service.com)获取第一个截获的请求的实际镜像扩展的URL,并将其存储到cookie以用于下一个请求。

的manifest.json

{
    "name": "InterceptMySite",
    "version": "0.1",
    "description": "My first Chrome extension",
    "permissions": ["webRequest", "webRequestBlocking", "cookies",
                    "*://mysite.com/*", "*://api.service.com/*"],
    "background": {
        "scripts": ["background.js"]
    },

    "manifest_version": 2
}

background.js

function setMirrorUrl(callback) {
        var req = new XMLHttpRequest();
        req.open('GET', 'http://api.service.com', false); // sync request
        req.send(null);
        req.onload = function() {
            callback(this.getResponseHeader('Mirror-Url'));
        }
    }
    function getMirrorUrl(callback) {
        chrome.cookies.get({url:'http://api.service.com',name:'mirror_url'}, function(cookie) {
            if ( ! cookie)
                return setMirrorUrl(callback);
            else
                return callback(cookie.value);
        });
    }
    chrome.webRequest.onBeforeRequest.addListener(
        function(info) {
            if(info.url.indexOf('api.service.com') != -1)
                return {cancel:false};

            getMirrorUrl(function(mirror_url){

                return {redirectUrl: info.url.replace(/mysite.com/i, mirror_url)};

            });

        },
        // filters
        {
            urls: [
                "*://mysite.com/*",
                "*://api.service.com/*"
            ]
        },
        // extraInfoSpec
        ["blocking"]
    );

一切正常除了一件事: getMirrorUrl()异步调用。因此, onBeforeRequest 事件侦听器在getMirrorUrl()完成之前完成。另外,getMirrorUrl必须以某种方式将结果传递给onBeforeRequest监听器。

我知道它必须重写为回调式,但我不知道如何。

1 个答案:

答案 0 :(得分:0)

你在做什么回调式!你要求一个cookie并与你的回调异步。

你可以同步进行API调用(虽然那会很难看),但是cookie" get"操作必须是异步的。因此,我认为您需要事先预加载镜像URL(例如,一旦加载页面),然后在单击链接时检索相应的URL。

我尝试的另一种方法是将redirectUrl设置为当前页面,异步加载镜像URL并在加载后立即触发页面更改(我不确定,我&# 39;从未通过扩展API完成此操作。)