简体   繁体   English

Leaflet 等待 promise 解决

[英]Leaflet wait for promise to resolve

I am extending Leaflet getTileUrl for some sort of caching tiles.我正在为某种缓存切片扩展Leaflet getTileUrl I use Vue but it shouldn't affect anything.我使用 Vue,但它不应该影响任何东西。 It currently looks like this:它目前看起来像这样:

   //step 1 
   L.TileLayer.MyLayer = L.TileLayer.extend({
        getTileUrl: function(coords) {
            
            var url = this.getLayerUrl(coords.z, coords.x, coords.y);

            return url;

        }.bind(this)
    });

    //step 2
    L.tileLayer.myLayer =  function() {
        return new L.TileLayer.MyLayer();
    }

    //step 3
    L.tileLayer.myLayer().addTo(this.getParent('main-map').map);

The problem is that the getLayerUrl function returns a promise.问题是getLayerUrl function 返回 promise。 Even when I tried to make getTileUrl async and than await for this.getLayerUrl (and also make async await step 2 and 3) or put .then(function(result) {return result;} after this.getLayerUrl, Leaflet show error in browser console that it is trying to get tile from url: GET http://localhost/project/public/[object%20Promise]即使我尝试使getTileUrl异步,而不是等待this.getLayerUrl (并且还使异步等待第 2 步和第 3 步)或在 this.getLayerUrl 之后放置 .then (function(result) {return result;} ,Leaflet 在浏览器中显示错误控制台尝试从 url 获取磁贴:GET http://localhost/project/public/[object%20Promise]

Also I should mention that this.getLayerUrl returns different url for every tile, it is actualy a blob url like: blob:http://localhost/f7c4298f-9e9d-423f-9d0b-3f7a301e433f but if the url is correctly returned leaflet doest have problem with it and the tile is correctly shown. Also I should mention that this.getLayerUrl returns different url for every tile, it is actualy a blob url like: blob:http://localhost/f7c4298f-9e9d-423f-9d0b-3f7a301e433f but if the url is correctly returned leaflet doest have问题和瓷砖正确显示。

The approach here would be not to provide a getLayerUrl method, but to replace the implementation of the createTile element.这里的方法不是提供getLayerUrl方法,而是替换createTile元素的实现。

A "noop" replacement that replaces the createTile implementation with the original createTile implementation looks like:原始createTile实现替换createTile实现的“noop”替换如下所示:

L.TileLayer.MyLayer = L.TileLayer.extend({
  getTileUrl: function (coords) {
    var tile = document.createElement("img");

    DomEvent.on(tile, "load", Util.bind(this._tileOnLoad, this, done, tile));
    DomEvent.on(tile, "error", Util.bind(this._tileOnError, this, done, tile));

    if (this.options.crossOrigin || this.options.crossOrigin === "") {
      tile.crossOrigin =
        this.options.crossOrigin === true ? "" : this.options.crossOrigin;
    }

    tile.alt = "";
    tile.setAttribute("role", "presentation");

    tile.src = this.getTileUrl(coords);

    return tile;
  }
});

With that implementation in mind, it's possible to set the src attribute of the HTMLImageElement in a asynchronous manner replacing the synchronous tile.src = this.getTileUrl(coords);考虑到该实现,可以以异步方式设置HTMLImageElementsrc属性,替换同步tile.src = this.getTileUrl(coords); with something like eg:例如:

asyncGetLayerUrl(coords)
  .then(function (url) {
    tile.src = url;
  })

And, for good measure, handle promise rejections by calling this._tileOnError , eg:并且,为了更好地衡量,通过调用this._tileOnError来处理 promise 拒绝,例如:

asyncGetLayerUrl(coords)
  .then(function (url) {
    tile.src = url;
  })
  .catch(
    function (err) {
      this._tileOnError(done, tile, err);
    }.bind(this)
  );

Unfortunately what you are trying to achieve is not possible.不幸的是,您想要实现的目标是不可能的。 The getTileUrl() method is expected to return the url directly, ie not wrapped in a promise. getTileUrl()方法预计会直接返回 url,即不包含在 promise 中。 However, you get the url from getLayerUrl that returns a promise.但是,您从getLayerUrl获得 url,它返回 promise。 You simply can't wait for the result of the promise synchronously inside getTileUrl() .您根本无法在getTileUrl()中同步等待 promise 的结果。

The await keyword suggests that this is possible but it isn't. await关键字表明这是可能的,但事实并非如此。 await is just syntactic sugar, a shorthand for chaining promises. await只是语法糖,是链接承诺的简写。 I give you a simple example.我给你一个简单的例子。

function getUrl() {
    return getAsyncUrl().then(url => {
         return transformUrl(url);
    });
}

async / await allows you to write it like this: async / await允许你这样写:

async function getUrl() {
    const url = await getAsyncUrl();
    return transformUrl(url);
}

But behind the scenes it still uses promises.但在幕后它仍然使用承诺。 An async function always returns a promise. async function 始终返回 promise。

Hope this helps, information based on this article希望这会有所帮助,基于本文的信息

L.TileLayer.YourLayer = L.TileLayer.extend({
 
  createTile: function (coords, done) {
    var tile = document.createElement('img');
    
    hereMakeSomeRemoteRequest().then(response => {
      tile.src = response.imageSrc
      done(null, tile)
    }, function (e) {
        console.log('error: ', e.message);
        tile.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; // empty gif 1x1 px
        done(e, tile)
    });
    return tile;
  }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM