您现在的位置是:主页 > news > 建设网站的企业邮箱网站建设服务/百度推广投诉热线

建设网站的企业邮箱网站建设服务/百度推广投诉热线

admin2025/5/5 6:35:36news

简介建设网站的企业邮箱网站建设服务,百度推广投诉热线,中核工建设集团网站,国外永久免费客服系统使用 Java 实现 setTimeout/setInterval场景之前想把 Java 代码中使用回调函数的方法改成 Promise 风格,苦思冥想而不得其解。然而突发奇想之下,吾辈尝试在 Java 中实现 JavaScript 的 setTimeout/setInterval,并在之后想到了如何封装回调为 …

建设网站的企业邮箱网站建设服务,百度推广投诉热线,中核工建设集团网站,国外永久免费客服系统使用 Java 实现 setTimeout/setInterval场景之前想把 Java 代码中使用回调函数的方法改成 Promise 风格,苦思冥想而不得其解。然而突发奇想之下,吾辈尝试在 Java 中实现 JavaScript 的 setTimeout/setInterval,并在之后想到了如何封装回调为 …

使用 Java 实现 setTimeout/setInterval

场景

之前想把 Java 代码中使用回调函数的方法改成 Promise 风格,苦思冥想而不得其解。然而突发奇想之下,吾辈尝试在 Java 中实现 JavaScript 的 setTimeout/setInterval,并在之后想到了如何封装回调为 Promise,所以便先在此将这个想法的写出来以供参考。

Promise 是 ES6 添加的一个重要的元素,它将回调函数压平为了一级调用,并在 ES7 的 async/await 中彻底改变了异步的使用方式!

实现

public class AsyncUtil {

private static final Logger log = LoggerFactory.getLogger(AsyncUtil.class);

/**

* 将当前线程休眠指定的时间

*

* @param millis 毫秒

*/

public static void sleep(long millis) {

try {

Thread.sleep(millis);

} catch (InterruptedException e) {

throw new RuntimeException(e);

}

}

/**

* 实现 JavaScript 中的 setTimeout

* 注:由于 {@link CompletableFuture#cancel(boolean)} 方法的限制,该定时器无法强制取消

*

* @param ms 等待时间

* @return 异步对象

*/

public static CompletableFuture setTimeout(long ms) {

return CompletableFuture.runAsync(() -> sleep(ms));

}

/**

* 实现等待指定资源加载完成

* 注:由于 {@link CompletableFuture#cancel(boolean)} 方法的限制,该定时器无法强制取消

*

* @param condition 临界条件

* @return 异步对象

*/

public static CompletableFuture waitResource(Supplier condition) {

return CompletableFuture.runAsync(() -> {

while (!condition.get()) {

sleep(100);

}

});

}

/**

* 实现 JavaScript 中的 setInterval 周期函数

* 该方法并不是非常精确的定时器,仅适用于一般场景,如有需要请使用 {@link ScheduledExecutorService} 类

* 注:由于 {@link CompletableFuture#cancel(boolean)} 方法的限制,该定时器无法强制取消

*

* @param ms 间隔毫秒数

* @param runnable 回调函数

* @return 永远不会完成的异步对象

*/

public static CompletableFuture setInterval(long ms, Runnable runnable) {

return CompletableFuture.runAsync(() -> {

//noinspection InfiniteLoopStatement

while (true) {

try {

runnable.run();

sleep(ms);

} catch (Exception e) {

log.error("使用 setInterval 发生异常: ", e);

}

}

});

}

}

使用

public class AsyncUtilTest {

private final Logger log = LoggerFactory.getLogger(getClass());

public static void main(String[] args) {

final AsyncUtilTest asyncUtilTest = new AsyncUtilTest();

asyncUtilTest.setTimeout();

asyncUtilTest.waitResource();

asyncUtilTest.setInterval();

AsyncUtil.sleep(4000);

}

@Test

public void setTimeout() {

log.info("setTimeout completed before time: {}", LocalDateTime.now());

AsyncUtil.setTimeout(1000)

.thenRunAsync(() -> log.info("setTimeout completed after time: {}", LocalDateTime.now()));

}

@Test

public void waitResource() {

log.info("waitResource completed before time: {}", LocalDateTime.now());

final AtomicInteger i = new AtomicInteger(1);

AsyncUtil.waitResource(() -> i.get() == 3)

.thenRunAsync(() -> log.info("waitResource completed after time: {}", LocalDateTime.now()));

AsyncUtil.sleep(2);

i.set(3);

}

@Test

public void setInterval() {

log.info("setInterval completed before time: {}", LocalDateTime.now());

final CompletableFuture future = AsyncUtil.setInterval(100, () -> log.info("setInterval in the loop, current time: {}", LocalDateTime.now()));

AsyncUtil.sleep(500);

future.complete(null);

AsyncUtil.sleep(1000);

}

}