使geoQuery.addGeoQueryEventListener()成为阻止操作

问题描述 投票:0回答:1

我在Firestore中保存了一份商店清单,其中包含一些虚拟数据和纬度/经度。我想在poi附近获得文件。为此,我使用了GeoFire库。现在,我能够从geoQuery.addGeoQueryEventListener()方法对内部数据进行排序,但是该方法不是阻塞操作,因此在geoQuery.addGeoQueryEventListener()返回排序列表之前,我的代码已退出。下面是代码片段:

    List<QueryDocumentSnapshot> doc = new ArrayList<>();
    List<String> businessIds = new ArrayList<>();
    Set<Business> businessSet = new HashSet<>();

    GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(latitude, longitude), 2000);
    geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {

        @Override
        public void onKeyEntered(String key, GeoLocation location) {
            // TODO Auto-generated method stub
            businessIds.add(key);
        }

        @Override
        public void onKeyExited(String key) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onKeyMoved(String key, GeoLocation location) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onGeoQueryReady() {
            // TODO Auto-generated method stub
            System.out.println("All initial data has been loaded and events have been fired!");
        }

        @Override
        public void onGeoQueryError(DatabaseError error) {
            // TODO Auto-generated method stub
            System.err.println("There was an error with this query: " + error);
        }

    });
    geoQuery.removeAllListeners();

    ApiFuture<QuerySnapshot> query = firestore.collection("business").whereIn("businessId", businessIds).get();
    businessSet = query.get().getDocuments().stream()
            .map(b -> b.toObject(Business.class)).collect(Collectors.toSet());
    return businessSet;

在上面的代码中,我的程序在可以将键添加到onKeyEntered()中的businessIds之前退出。

java google-cloud-firestore firebase-admin geofire geofirex
1个回答
1
投票

[请注意,我不知道您使用的是那些API,但是从理论上讲,您应该可以使用CompletableFuture,例如,使用类似这样的东西(未经测试):

private CompletableFuture<List<String>> runGeoQuery(double latitude, double longitude) {
  CompletableFuture<List<String>> future = new CompletableFuture<>();
  GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(latitude, longitude), 2000);
  geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {

    private final List<String> businessIds = new ArrayList<>();

    @Override
    public void onKeyEntered(String key, GeoLocation location) {
      businessIds.add(key);
    }

    @Override
    public void onKeyExited(String key) {
    }

    @Override
    public void onKeyMoved(String key, GeoLocation location) {
    }

    @Override
    public void onGeoQueryReady() {
      future.complete(businessIds);
    }

    @Override
    public void onGeoQueryError(DatabaseError error) {
      future.completeExceptionally(error);
    }

  });
  return future;
}

然后,您可以使用#thenApply或#thenCompose构成结果,也可以仅使用#get进行阻止。

旁注,请确保根据您的情况进行屏蔽是可以的。 not应该很好的一个示例是,运行此代码的线程来自HTTP请求池(例如Netty),因为这可能会引起争用并停止您的Web服务器处理新请求。

© www.soinside.com 2019 - 2024. All rights reserved.