一尘不染

设计模式以处理Java中的异步响应

java

我看到了很多解决方案,但没有一个能让我满意。

监听方式

捕获结果后,将在onResult方法中执行处理。

public interface GeolocationListener {
public void onResult(Address[] addresses);
public void onError(Exception e);
}

这个解决方案并不令我满意,因为我想用main方法处理结果。我讨厌这个接口,因为当返回响应时,它将在onResult中进行处理,从而导致处理链,并且无法返回“
main”方法。

servlet方式

public class SignGuestbookServlet extends HttpServlet {

    public void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws IOException {
        // ...
        resp.sendRedirect("/guestbook.jsp");
    }
}

没有公开的Java代码调用servlet。所有配置都在web.xml中完成

我想要的方式

等待这样的回应

Response a = getResponse();
// wait until the response is received, do not go further
// process
Response b = getResponse();
// wait until the response is received, do not go further
process(a,b);

是否有一种设计模式来处理异步请求并等待上述响应?除了听众以外的其他方式。请没有库或框架。

编辑
到目前为止,谢谢。我没有给你完整的画面,所以我公开了我开始实施的Geolocation类。我不知道如何实现该方法。有人可以显示“如何”吗?他(或她)还必须实现侦听器以检索结果

private Address getFullAddress (String text, AddressListener listener, ... ){

    // new Geolocation(text, listener, options).start() 
    // implements Geolocation.GeolocationListener   
    // how to return the Address from the onResult ?
}

阅读 225

收藏
2020-12-03

共1个答案

一尘不染

异步代码始终可以使同步。最简单/最简单的方法是进行异步调用,然后进入一个while循环,该循环仅使当前线程休眠,直到返回值为止。

编辑: 将异步回调转换为同步代码的代码-还是粗略的实现:

import java.util.concurrent.*;

public class MakeAsynchronousCodeSynchronous {
    public static void main(String[] args) throws Exception {
        final Listener listener = new Listener();
        Runnable delayedTask = new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    throw new IllegalStateException("Shouldn't be interrupted", e);
                }
                listener.onResult(123);

            }
        };
        System.out.println(System.currentTimeMillis() + ": Starting task");
        Executors.newSingleThreadExecutor().submit(delayedTask);
        System.out.println(System.currentTimeMillis() + ": Waiting for task to finish");
        while (!listener.isDone()) {
            Thread.sleep(100);
        }
        System.out.println(System.currentTimeMillis() + ": Task finished; result=" + listener.getResult());
    }

    private static class Listener {
        private Integer result;
        private boolean done;

        public void onResult(Integer result) {
            this.result = result;
            this.done = true;
        }

        public boolean isDone() {
            return done;
        }

        public Integer getResult() {
            return result;
        }
    }
}

您也可以按照hakon的答案建议使用CountDownLatch。它将做基本上相同的事情。我还建议您熟悉java.util.concurrent包,以获取更好的线程管理方法。最后,仅仅因为您 可以
做到这一点就不是一个好主意。如果您正在使用基于异步回调的框架,那么与学习如何有效使用框架相比,尝试颠覆它可能要好得多。

2020-12-03