繁体   English   中英

Java中的异步执行流程

[英]Asynchronous flow of execution in Java

我正在编写一个方法,我想在其中查询数据库并在查询完成后执行另一种方法。 但是,由于对数据库的调用是异步的,我似乎无法弄清楚如何在数据库调用完成之前停止主要执行流程,如下所示:

public void getUserFromEmail(String email) {
    Firebase usersRef = rootRef.child("users");

    //Asynchronous database call, want to stop everything else 
    usersRef.orderByKey().equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            System.out.println(firebaseError.getMessage());
        }
    });
    //Perform some more operations after database call is finished
}

我习惯于在 Nodejs 中使用异步回调,但我不知道在 Java 中是否有任何等效的方法来控制执行流程。 有什么简单的方法可以实现我想做的事情吗?

你不能停止主流程,主线程会继续。 (除非您以其他方式停止它,但这会导致“应用程序无响应”,所以不要)。

只需在回调中执行操作即可。

public void getUserFromEmail(String email) {
    Firebase usersRef = rootRef.child("users");

    //Asynchronous database call, want to stop everything else 
    usersRef.orderByKey().equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            // Perform some more operations after database call is finished
            // OR... callSomeMethod();
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            System.out.println(firebaseError.getMessage());
        }
    });

}

public void callSomeMethod() {
    // Perform some more operations after database call is finished
}

如果您来自 Node 背景,那么这可能看起来很相似。 将函数传递给getUserFromEmail

public void otherMethod() {
    getUserFromEmail("steve@example.com", new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            // Perform some more operations after database call is finished
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            System.out.println(firebaseError.getMessage());
        }
    });
}

public void getUserFromEmail(String email, ValueEventListener listener) {
    rootRef.child("users")
        .orderByKey()
        .equalTo(email)
        .addListenerForSingleValueEvent(listener);
}

如果你真的想使用锁,你可以控制流程。 例如使用CountdownLatch

public DataSnapshot getUserFromEmail(String email) throws InterruptedException {
    AtomicReference<DataSnapshot> dataSnapshotRef = new AtomicReference<DataSnapshot>();
    CountDownLatch completeSignal = new CountDownLatch(1);

    Firebase usersRef = rootRef.child("users");

    //Asynchronous database call, want to stop everything else 
    usersRef.orderByKey().equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            dataSnapshotRef.set(dataSnapshot);
            // Causes execution of the waiting thread to continue
            // from the `await` call
            completeSignal.countDown();
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            completeSignal.countDown();
        }
    });

    // Execution on this thread pauses at the `await` call until
    // countDown has been called from another thread.
    completeSignal.await();

    // Do stuff after onDataChanged or onCancelled has been called
    DataSnapshot dataSnapshot = dataSnapshotRef.get();
}

然而,这种方法会阻塞执行getUserFromEmail的线程,直到 Firebase 返回一些数据。 特别是,如果您从 UI 线程调用getUserFromEmail ,那么这将阻塞 UI 线程并导致 ANR。

最好遵循这样的回调方法:

public DataSnapshot getUserFromEmail(String email, ValueEventListener listener) {
    Firebase usersRef = rootRef.child("users");

    //Asynchronous database call, want to stop everything else 
    usersRef.orderByKey().equalTo(email).addListenerForSingleValueEvent(listener);
}

public void getUserAndThenDoSomething() {
    getUserFromEmail("bob@example.com", new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            // Do stuff after getting the email here
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
        }
    });
}

暂无
暂无

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

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