如何使用chrome.storage.local.get和XMLHttpRequest同步执行函数?

时间:2015-07-12 04:58:20

标签: javascript jquery google-chrome google-chrome-extension

function get_pps_params(callback)
{
    var ppsParams = null;
    chrome.storage.local.get(['ppsParams'], function(result) {
        if ($.isEmptyObject(result))
        {
            var oReq = new XMLHttpRequest();
            oReq.open("GET", CLOUD_SERVER + 'get_pps_params', true);
            oReq.responseType = "arraybuffer";

            oReq.onload = function (oEvent) {
                console.log("Got pps params compressed!");
                ppsParams = oReq.response; // Note: not oReq.responseText
                chrome.storage.local.set({ppsParams: _arrayBufferToBase64(ppsParams)});
            };

            oReq.send();
        }
        else
        {
            ppsParams = _base64ToArrayBuffer(result.ppsParams);
        }
        callback(ppsParams);
    });
}

我使用上述函数从本地存储中检索某些参数,如果它们不在本地存储中,则chrome.storage.local.get回调会将数据请求发送到服务器。这使整个get_pps_params异步(显然)。那么如何让它同步执行呢?我读了一些关于jQuery.Deferred的内容,但是并不理解它。

由于XMLHttpRequest的异步特性,当前callback(ppsParams)如果请求被发送到服务器,则为null。

2 个答案:

答案 0 :(得分:2)

与上次类似的解决方案

override func viewDidLoad() {
    super.viewDidLoad()

    // Set map view delegate with controller
    self.mapView.delegate = self

    let newYorkLocation = CLLocationCoordinate2DMake(40.730872, -74.003066)
    // Drop a pin
    let dropPin = MKPointAnnotation()
    dropPin.coordinate = newYorkLocation
    dropPin.title = "New York City"
    mapView.addAnnotation(dropPin)
}

答案 1 :(得分:0)

如果你真的想使用jquery.Deferred

function get_pps_params()
{
    var ppsParams = null;
    var def = jQuery.Deferred();
    chrome.storage.local.get(['ppsParams'], function(result) {
        if ($.isEmptyObject(result))
        {
            var oReq = new XMLHttpRequest();
            oReq.open("GET", CLOUD_SERVER + 'get_pps_params', true);
            oReq.responseType = "arraybuffer";

            oReq.onload = function (oEvent) {
                console.log("Got pps params compressed!");
                ppsParams = oReq.response; // Note: not oReq.responseText
                chrome.storage.local.set({ppsParams: _arrayBufferToBase64(ppsParams)});
                def.resolve(ppsParams);
            };

            oReq.send();
        }
        else
        {
            ppsParams = _base64ToArrayBuffer(result.ppsParams);
            def.resolve(ppsParams);
        }
    });
    return def.promise();
}

而不是

get_pps_params(someFunc);

使用

get_pps_params().then(someFunc);
  

使用适当的Promise可以获得相同的结果 - 标配任何体面的浏览器,或者使用polyfill用于非体面的浏览器

function get_pps_params()
{
    return new Promise(function(resolve, reject) {
        var ppsParams = null;
        chrome.storage.local.get(['ppsParams'], function(result) {
            if ($.isEmptyObject(result))
            {
                var oReq = new XMLHttpRequest();
                oReq.open("GET", CLOUD_SERVER + 'get_pps_params', true);
                oReq.responseType = "arraybuffer";

                oReq.onload = function (oEvent) {
                    console.log("Got pps params compressed!");
                    ppsParams = oReq.response; // Note: not oReq.responseText
                    chrome.storage.local.set({ppsParams: _arrayBufferToBase64(ppsParams)});
                    resolve(ppsParams);
                };

                oReq.send();
            }
            else
            {
                ppsParams = _base64ToArrayBuffer(result.ppsParams);
                resolve(ppsParams);
            }
        });
    });
}

再次使用

get_pps_params().then(someFunc);

方法