`
rainsilence
  • 浏览: 160792 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

用Java实现Promise的难点总结

阅读更多

自Promise被纳入ECMAScript6标准后,各大浏览器几乎都实现了Promise标准。

以下是ecmascript6里promise的典型用法,为了解决一个线程的任务完成后,再去执行另一个任务。

var promise = new Promise(function(resolve, reject) {
      $.ajax({
           success: function() {
                 resolve();
           },
           failure: function() {
                 reject();
           }
      })
});

promise.then(function() {
       //调用了resolve或者reject之后
});

 

Java实现Promise相比较ECMAScript6来说,有些不同。

Javascript不管怎么样都是单线程的,即使ajax在浏览器内核层面表现出多线程,但是执行到js端还是单线程的。而在java上实现promise机制则复杂的多。具体表现在:

1)即使在上一个线程执行任务后,下一个任务可以在同一个线程中执行,但是加入任务的操作不得不是同步的

Netty4源码:io.netty.util.concurrent.DefaultPromise

    @Override
    public Promise<V> addListener(GenericFutureListener<? extends Future<? super V>> listener) {
        if (listener == null) {
            throw new NullPointerException("listener");
        }

        if (isDone()) {
            notifyLateListener(listener);
            return this;
        }
        //加入时必须同步
        synchronized (this) {
            if (!isDone()) {
                if (listeners == null) {
                    listeners = listener;
                } else {
                    if (listeners instanceof DefaultFutureListeners) {
                        ((DefaultFutureListeners) listeners).add(listener);
                    } else {
                        final GenericFutureListener<? extends Future<V>> firstListener =
                                (GenericFutureListener<? extends Future<V>>) listeners;
                        listeners = new DefaultFutureListeners(firstListener, listener);
                    }
                }
                return this;
            }
        }

        notifyLateListener(listener);
        return this;
    }

 

2)在多个平行任务(线程)结束后,再去执行一个任务的case (Promise.all)的时候,判断任务是否结束的计数操作也不得不是同步的。

Netty源码:io.netty.channel.group.DefaultChannelGroupFuture

    private final ChannelFutureListener childListener = new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            boolean success = future.isSuccess();
            boolean callSetDone;
            // 判断所有的task是否已经结束也必须同步
            synchronized (DefaultChannelGroupFuture.this) {
                if (success) {
                    successCount ++;
                } else {
                    failureCount ++;
                }

                callSetDone = successCount + failureCount == futures.size();
                assert successCount + failureCount <= futures.size();
            }

            if (callSetDone) {
                if (failureCount > 0) {
                    List<Map.Entry<Channel, Throwable>> failed =
                            new ArrayList<Map.Entry<Channel, Throwable>>(failureCount);
                    for (ChannelFuture f: futures.values()) {
                        if (!f.isSuccess()) {
                            failed.add(new DefaultEntry<Channel, Throwable>(f.channel(), f.cause()));
                        }
                    }
                    setFailure0(new ChannelGroupException(failed));
                } else {
                    setSuccess0();
                }
            }
        }
    };

 

分享到:
评论

相关推荐

    java sctipt学习不求人

    回调函数、Promise和async/await提供了处理异步操作的方法,理解和掌握这些,可以有效解决JavaScript中的“回调地狱”问题。 除此之外,熟悉JavaScript的内置对象和方法,如Array的迭代方法(`map()`, `filter()`, ...

    党建工作小秘书微信小程序.zip

    3. **编码实现**:使用Java和微信小程序开发工具进行编码,搭建服务器环境。 4. **测试调试**:进行单元测试和整体功能测试,修复问题。 5. **上线部署**:通过微信开发者工具提交审核,完成上线。 五、技术难点与...

    JavaScript源码大全

    JavaScript源码大全是一本专为Java程序员或对编程有浓厚兴趣的读者设计的书籍,它深入探讨了JavaScript这门广泛应用于网页开发、浏览器交互及现代Web应用的核心语言。JavaScript不仅在前端开发中扮演着重要角色,...

    面试

    异步编程是JavaScript中的难点,主要涉及回调函数、Promise、async/await。回调函数是处理异步操作的原始方式,但可能导致“回调地狱”问题。Promise解决了这一问题,提供了一种链式处理异步操作的方法。async/await...

    进行异步功能集成测试时,越过空隙

    在JavaScript、Python、Java等语言中,异步操作通常通过回调函数、Promise、async/await等方式实现。 2. **异步功能的集成测试难点**: - **时间依赖性**:异步操作的结果可能会在不确定的时间点到达,这增加了...

    0x40-hues-of-brendan-eich:0x40 Megumi Hues 用一种理智、合理、高质量的编程语言重新创建

    6. **JavaScript的挑战**:JavaScript的全局作用域、异步编程模型(回调地狱、Promise、async/await)、以及对闭包和原型链的理解,都是开发者常常遇到的难点。 7. **学习资源**:学习JavaScript可以参考MDN Web...

Global site tag (gtag.js) - Google Analytics