加载图像后如何返回

时间:2016-07-25 11:46:14

标签: javascript

首先,我必须承认,stackoverflow(thisthis和其他无数人)中有几十个类似的问题,但所有这些问题都得到了很好的解决。回调函数或只是将代码放在此image.onload事件中:

image.onload = function () {
    //do other stuff that should be done right after image is loaded
}

但这不是我的情况。这是我的函数的签名,负责加载图像:

function patternBuilder (index) {
    var pattern, image, ...
    ...
    image = new Image();
    image.id = "_" + index + "_";
    image.src = "images/_" + index + "_.png";  
    image.onload = function () {
        pattern = ctx.createPattern(image, "repeat");
    }
    return pattern; // !!!! may return undefined if image is not yet loaded
}

所以,我需要回来!我必须这样做,我没有其他机会。我必须遵循这个签名的原因是,这个模式被一些外部库函数使用,如下所示:

style: function (feature) {
   var pattern = patternBuilder(feature.get("index"));
   var style = new ol.style.Style({
       fill: new ol.style.Fill({
           color: pattern
       })
   });
   return style;
}

因此,即使我可以更改patternBuilder函数的逻辑,我仍然无法更改外部库函数。此外部函数使用patternBuilder并返回样式变量本身。所以,没有回调的余地。

2 个答案:

答案 0 :(得分:1)

这里如何使用promises

返回图片承诺的简单包装:

//takes an url and returns a promise of a (loaded) Image.
function getImage(url){
    return new Promise(function(){
        var image = new Image();
        image.onload = function(){ resolve(image); };
        image.onerror = reject; //TODO: resolve that to sth. better
        image.src = url;
    });
}

和你的patternBuilder

function patternBuilder (index) {
    //returns now a pattern-promise
    return getImage( "images/_" + index + "_.png" ).then(function(image){
        //image.id = "_" + index + "_"; //what exactly is this ID for?
        return ctx.createPattern(image, "repeat");
    });
}

//you may want to add some caching
var patternCache = Object.create(null);
function patternBuilder(index) {
    if(!patternCache[index]){
        patternCache[index] = getImage( "images/_" + index + "_.png" ).then(image => ctx.createPattern(image, "repeat"));
    }
    //still returns pattern-promise, but some may have been resolved a "long time" ago.
    return patternCache[index];
}

以及您使用该模式的功能:

style: function(feature) {
    //returns a style-promise
    return patternBuilder(feature.get("index")).then(function(pattern){
        return new ol.style.Style({
            fill: new ol.style.Fill({
                color: pattern
            })
        })
    })
}

答案 1 :(得分:0)

你尝试过使用诺言吗?您可以控制de callback,以便在加载图像时可以返回该功能。