我对异步函数没什么困难。 getImageSizeByUrl()中的异步函数可以使用$ .Deferred()来处理。
function getImageSizeByUrl(url) {
var deferredReady = $.Deferred();
var tmpImg = new Image();
tmpImg.src = url;
// asynchronous function
$(tmpImg).on('load',function(){
getImageSizeByUrlWidth = tmpImg.width;
getImageSizeByUrlHeight = tmpImg.height;
deferredReady.resolve();
});
return deferredReady.promise();
}
但现在我还有另外两个问题。在lower函数中,函数 $。when 本身是异步的。所以它只包装了这个问题。所以函数 chrome.webRequest.onBeforeRequest.addListener()完成,而不等待 getImageSizeByUrl()的返回。如何在这个棘手的情况下获得同步行为?
我的第二个问题是下部函数中的嵌套返回值。 返回{redirectUrl:" https://www.google.de/images/srpr/logo11w.png"}; 和 return {} 应该是父函数函数的返回值(信息)的
(背景:chrome扩展的下层监听器功能在加载之前检查每个图像。监听器需要一个返回值来重定向或允许图像加载。但是监听器功能并不等待上层的结果function getImageSizeByUrl并返回一个空值。)
// listener for image loading
chrome.webRequest.onBeforeRequest.addListener(
function(info) {
console.log("test1");
$.when(
getImageSizeByUrl(info.url)
).done(
function() {
// for example: if image has to big height or width, load alternative image
if(getImageSizeByUrlHeight > 200 || getImageSizeByUrlWidth > 200) {
// load alternative image
console.log("test3");
return {redirectUrl: "https://www.google.de/images/srpr/logo11w.png"};
} else {
// image is not big. allow loading
console.log("test3");
return {};
}
}
);
console.log("test3");
},
{
urls: [
"<all_urls>",
],
types: ["image"]
},
["blocking"]
);
希望有人能够帮助我/给我一些提示。 :)
最好的问候
答案 0 :(得分:0)
您可能会发现编写一个返回&#34; promisified Image&#34;的构造函数更有用,即使用返回promise的自定义window.Image
方法的.setSrc()
实例。< / p>
这样的事情(未经测试)应该这样做:
function PromisifiedImg() {
var img = new Image();
img.setSrc = function(src, limits) {
var dfrd = $.Deferred();
img.onload = function() {
if(limits && (img.width > limits.width || img.height > limits.height)) {
var error = new Error('img dimension(s) exceed limits');
error.number = 101; // 101 is arbitrary
dfrd.reject(error);
} else {
dfrd.resolve(img);
}
};
img.onerror = function(e) {
e.number = e.number || 0;
dfrd.reject(e);
};
img.src = src;
return dfrd.promise();
};
return img;
}
现在您可以调用返回的图片.setSrc(...)
方法,而不是.src = '...'
您的....addListener()
处理程序可能如下所示:
chrome.webRequest.onBeforeRequest.addListener(
function(info) {
var img = new PromisifiedImg();
img.setSrc(info.url, { width:200, height:200 }).then(null, function(e) {
if(e.number === 101) { // detect the custom error condition
console.log(e.message);
return img.setSrc("https://www.google.de/images/srpr/logo11w.png");
}
});
},
{ urls: [ "<all_urls>" ], types: ["image"] },
["blocking"]
);
这样做的一个好处是返回的Image是可重用的。对.setSrc()
的第二次调用将在Image的同一个实例上运行,但会返回一个新的承诺。
注意:我没有尝试将传递给它的其他参数渗透到chrome.webRequest.onBeforeRequest.addListener()
包装器中。在偶然看一眼documentation后,这看起来可能是错误的做法。因此,这个答案可能只能提供部分解决方案。