【问题标题】:Why is Vert.x executing code synchronously?为什么 Vert.x 会同步执行代码?
【发布时间】:2021-09-01 13:02:27
【问题描述】:

在理解代码执行流程方面需要帮助。 在调用下面的sayHi() 方法时,首先执行onSuccess 处理程序,然后执行return 语句。 我的理解是该函数将立即返回,然后onSuccess 处理程序将被执行。

public String sayHi() {
    sayHello().onSuccess(s  -> {
      System.out.println(s);
    });
    return "hi";
  }

  public Future<String> sayHello() {
    String s1 = "hello";
    return Future.succeededFuture(s1);
  }

编辑:我试图将它与 JavaScript Promises 进行比较,其中传递给 then 方法的函数总是在其余语句执行后执行。就像调用下面的test 方法会打印'hi','bye' 和then 'Success'

    var promise2 = new Promise((resolve, reject) => {
        resolve("Success!")
    });
      
   function test() {
      console.log("hi");
      promise2.then((value) => {
        console.log(value);
      });
      console.log("bye");
  }

【问题讨论】:

    标签: javascript java asynchronous future vert.x


    【解决方案1】:

    来自the documentation

    你不能直接与未来的结果互动,而是你 需要设置一个处理程序将在未来完成时调用 并且结果是可用的,就像任何其他类型的事件一样。

    所以Future 结果立即可用,并且没有需要等待的 I/O 任务:例如 HTTP 响应,或从文件系统读取......等等。

    您的所有代码都在一个线程中运行,您可以自己验证:

    public String sayHi() {
        sayHello().onSuccess(s  -> {
          System.out.println("Thread name ==> " + Thread.currentThread().getName()); // e.g: Thread name ==> main
          System.out.println(s);
        });
        return "hi";
      }
    
      public Future<String> sayHello() {
        System.out.println("Thread name ==> " + Thread.currentThread().getName()); // e.g: Thread name ==> main
        String s1 = "hello";
        return Future.succeededFuture(s1);
      }
    

    但下面的代码可能会以不同的顺序运行(我们在这里做 I/O 任务):

      public String sayHi() {
        sayHello().onSuccess(s  -> {
          System.out.println(s);
        });
        return "hi";
      }
    
      public Future<String> sayHello() {
        var vertx = Vertx.vertx();
        var fs = vertx.fileSystem();
        return fs.props( ".").map(fileProps -> "In getHelloFuture() method");  // I/O task
      }
    

    【讨论】:

      【解决方案2】:

      问题在于Future.succeededFuture(s1) 返回一个已完成的Future,它与 ExecutionContext 无关。

      由于它已经完成并且没有与 ExecutionContext 关联,它会同步执行 onSuccess() 处理程序。

      您需要告诉 vert.x 在单独的线程上为您创建Future&lt;String&gt;。你可以试试

      import io.vertx.core.Future;
      import io.vertx.core.Vertx;
      
      public class Async {
          private static Vertx vertx;
      
          public static void main(String[] args) {
              vertx = Vertx.vertx();
              System.out.println(sayHi());
              vertx.close();
          }
          public static String sayHi() {
              sayHello().onSuccess(s  -> {
                  System.out.println(s);
              });
              return "hi";
          }
      
          public static Future<String> sayHello() {
              return vertx.executeBlocking(p -> {
                  String s1 = "hello";
                  p.complete(s1);
              });
          }
      }
      

      注意:我对 vert.x 没有太多经验,所以可能会有更好的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-16
        • 1970-01-01
        相关资源
        最近更新 更多