简体   繁体   English

如何遍历Java / JavaScript中的回调函数?

[英]How can I loop over Callback functions in Java/JavaScript?

I have a list of books: 我有一本书的清单:

List<Book> books = new ArrayList<Book>();

Now I will iterate over this list an call a function myFunction() on each object. 现在,我将遍历此列表,对每个对象调用一个函数myFunction()。

for(Book book: books) {

  book.myFunction();

}

Now, I have a Callback interface which is called when myFunction() finishes: 现在,我有一个Callback接口,当myFunction()完​​成时会调用该接口:

public interface MyHandler {
  void onDone();
}

So myFunction is something like: 所以myFunction是这样的:

public void myFunction(MyHandler handler) {

   ...
   handler.onDone();

}

How can I iterate over a list of books and call myFunction(MyHandler handler)? 如何遍历书籍清单并调用myFunction(MyHandler handler)?

Note that you can only continue after onDone() is called. 请注意,只有在调用onDone()之后才能继续。

The only thing that doesn't fit is your call to myFunction() , which result in a compile error because the MyHandler parameter is missing. 唯一不合适的是您对myFunction()调用,这会导致编译错误,因为缺少MyHandler参数。

You just have to provide an object that implements MyHandler to your myFunction() method. 您只需MyHandler myFunction()方法提供一个实现MyHandler的对象。 You can do this via an anonymous class like this: 您可以通过这样的匿名类来做到这一点:

for(Book book: books) {
    book.myFunction(new MyHandler() {
        void onDone() {
            // put some code you want to execute here
        }
    });
}

Side note: For posterity, in a context where you can use Java 8, you can even use a lambda expression instead of the anonymous class: 旁注:为了后代,在可以使用Java 8的上下文中,您甚至可以使用lambda表达式代替匿名类:

for(Book book: books) {
    book.myFunction(() -> { /* insert code for onDone() here */ });
}

Since you've tagged this as GWT i'm going to assume that your myFunction() call is actaully doing something asynchronous, and that is why you can't simply wait for it to return. 由于您已将其标记为GWT,因此我将假设myFunction()调用实际上是在做异步操作,这就是为什么您不能简单地等待它返回。 In this case you could do the following, although it's a bit messy: 在这种情况下,您可以执行以下操作,尽管有点麻烦:

final Iterator<Book> iter = books.iterator();
MyHandler handler = new MyHandler() {
    @Override
    public void onDone() {
        if (iter.hasNext()) 
            iter.next().myFunction(this);
    }
};

//
// Start it going
//
if (iter.hasNext()) 
    iter.next().myFunction(handler);

Note that this is now recursive , so if you have a lot of book objects the call stack is going to get quite deep, and this imposes an upper limit on the number of books before you overflow the stack (an upper limit that you can't reliably know , either) This is not such a problem if you're using a GWT service to trigger the callback, since the stack will have unwound due to the network stuff. 请注意,这现在是递归的 ,因此,如果您有很多书本对象,则调用堆栈会变得很深,这会在堆栈溢出之前对书本数量施加上限(您可以设置一个上限)牛逼可靠地知道 ,无论是)这是没有这样的问题,如果您使用的是GWT服务触发回调,因为stack将解开由于网络的东西。

I don't mean to second-guess you here, but if you are calling an async gwt service then it's going to result in a lot of calls back and forth over the network. 我的意思不是在这里猜测您,但是如果您正在调用async gwt服务,那么它将导致通过网络来回调用。 If this is the case then you could consider simply passing a list of Book objects to be processed to the service, instead of sending them one at a time. 如果是这种情况,那么您可以考虑简单地将要处理的Book对象列表传递给服务,而不是一次发送一个。

To avoid the async calls, create a method on the server that loops thru the books and thus avoiding the rescursive calls. 为了避免异步调用,请在服务器上创建一个遍历书籍的方法,从而避免递归调用。 So you could gave just one call processMybooks(Books) 这样您就可以只进行一次通话过程

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

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