加载图像后如何返回

Jac*_*ian 6 javascript

首先,我必须承认,stackoverflow中有很多类似的问题(这个,这个和其他的无数个),但是所有这些问题都可以通过回调函数很好地解决,或者简单地将代码放在这个image.onload事件中:

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

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

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
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Tho*_*mas 1

这是如何与 Promise 一起使用的

返回图像承诺的简单包装器:

//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;
    });
}
Run Code Online (Sandbox Code Playgroud)

和你的模式生成器

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];
}
Run Code Online (Sandbox Code Playgroud)

以及您使用模式的功能:

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
            })
        })
    })
}
Run Code Online (Sandbox Code Playgroud)