首页 \ 问答 \ 链接一系列异步调用(Chain a series of asynchronous calls)

链接一系列异步调用(Chain a series of asynchronous calls)

我有一系列的异步操作

private void doSomething(){
  get("/something", new Callback(){
    void onComplete(String data){
      updateUi(something, data);           
      doSomethingElse();
    }
  });
}

private void doSomethingElse(){
  get("/something/else", new Callback(){
    void onComplete(String data){
      updateUi(somethingElse, data);
      doYetAnotherThing();
    }
  });
}

private void doYetAnotherThing(){
  get("/yet/another/thing", new Callback(){
    void onComplete(String data){
      updateUi(yetAnotherThing, data);
      allDone();
    }
  });
}

这有几个问题:

  1. 由于每个回调都与“下一步”有内在联系,因此无法在其他地方重复使用任何回调
  2. 重新排序操作或插入其他操作是非直观的,并涉及到所有地方跳跃。

我已经看过以下选项来减轻这一点:

  1. ExecuterService#invokeAll - 我没有看到这个解决方案如何在没有阻塞的情况下使用。
  2. RxJava--如果可以的话,我宁愿避免在我的应用程序中出现这种范式转变!
  3. 番石榴的ListenableFutures及其transform方法。 我看到这在互联网螺母周围的少数地方提到,我真的不知道这将如何解决我的问题。

所以,问题是:在Java中链接一系列异步调用的好模式是什么? 因为我需要一个适用于Android应用程序的解决方案,所以需要使用Java 7。


I have a series of asynchronous operations

private void doSomething(){
  get("/something", new Callback(){
    void onComplete(String data){
      updateUi(something, data);           
      doSomethingElse();
    }
  });
}

private void doSomethingElse(){
  get("/something/else", new Callback(){
    void onComplete(String data){
      updateUi(somethingElse, data);
      doYetAnotherThing();
    }
  });
}

private void doYetAnotherThing(){
  get("/yet/another/thing", new Callback(){
    void onComplete(String data){
      updateUi(yetAnotherThing, data);
      allDone();
    }
  });
}

This suffers from few problems:

  1. Cannot reuse any of the callbacks elsewhere since each is intrinsically tied to the "next step"
  2. Re-ordering operations or inserting another operation is non-intuitive and involves jumping all over the place.

I have looked at the following options to mitigate this:

  1. ExecuterService#invokeAll - I don't see how this solution can be used without blocking.
  2. RxJava - I would prefer to avoid such a paradigm shift in my application if I can!
  3. Guava's ListenableFutures and its transform method. I saw this referred to in few places around the interwebs nut I honestly don't see how this would solve my problem.

So, the question is: What would be a good pattern to chain a series of asynchronous calls in Java? Looking for a solution that works with Java 7 since I need this for an Android app.


原文:https://stackoverflow.com/questions/26059300
更新时间:2022-01-26 13:01

最满意答案

这应该让你开始http://jsfiddle.net/0ao9oa7a/

  • 获取所有记录的点
  • 过滤出相近的点(我使用5个像素)
  • 找出每对连续点的角度(atan2)
  • 找出每对连续角度之间的绝对差异
    • 在最大差异之前丢弃所有角度
  • 平均剩余的角度(平均所有点矢量然后atan2回到一个角度)

function process(points) {
    if(points.length === 0) { 
        txt = "Not enough points\n" + txt;
        return null; 
    }
    // compress points, removing those that are too close together
    var newPoints = [];
    newPoints.push(points[0]);
    for(var i = 1; i < points.length; i++) {
        if(Math.sqrt(Math.pow(points[i].x - newPoints[newPoints.length - 1].x, 2) + Math.pow(points[i].y - newPoints[newPoints.length - 1].y, 2)) > 5) {
            newPoints.push(points[i]);
        }
    }
    points = newPoints;
    if(points.length < 2) { 
        txt = "Not enough points\n" + txt;
        return null; 
    }
    // get all of the angles
    var angles = [];
    for(var i=0; i < points.length - 1; i++) {
        var rad = Math.atan2(points[i + 1].y - points[i].y, points[i + 1].x - points[i].x);
        angles[i] = rad;
        txt += "x: " + (points[i].x|0) + " y: " + (points[i].y|0) + " x: " + (points[i+1].x|0) + " y: " + (points[i+1].y|0) + " [" + ((rad * 180 / Math.PI)|0) + "]" + "\n";
    }
    txt += "\n";
    // get all of the diffs between angles
    // save the index of the max diff
    var absDiffs = [];
    var maxDiff = -1;
    var maxDiffAngleIndex = -1;
    for(var i=0; i < points.length - 1; i++) {
        var delta = Math.abs(angles[i] - angles[i + 1]);
        if(delta >= maxDiff) {
            maxDiff = delta;
            maxDiffAngleIndex = i + 1;
        }
    }
    if(maxDiffAngleIndex == -1) {
        txt = "Angle: " + angles[0] + " : " + (angles[0] * 180 / Math.PI) + "\n" + txt;
        return angles[0];
    } else if(maxDiffAngleIndex == angles.length - 1) {
        txt = "Angle: " + angles[angle.length - 1] + " : " + (angles[angles.length - 1] * 180 / Math.PI) + "\n" + txt;
        return angles[angles.length - 1];
    } else {
        // find the average angle from the index to the end
        var sumX = 0;
        var sumY = 0;
        for(var i = maxDiffAngleIndex; i < angles.length; i++) {
            sumX += Math.cos(angles[i]);
            sumY += Math.sin(angles[i]);
        }
        var avgX = sumX / (angles.length - maxDiffAngleIndex);
        var avgY = sumY / (angles.length - maxDiffAngleIndex);
        //
        var avgAngle = Math.atan2(avgY, avgX);
        txt = "Angle: " + avgAngle + " : " + (avgAngle * 180 / Math.PI) + "\n" + txt;
        return avgAngle;
    }
}

This should get you started http://jsfiddle.net/0ao9oa7a/

  • Get all of the recorded points
  • Filter out points that are close together (I use 5 pixels)
  • Find the angles of each consecutive pair of points (atan2)
  • Find the absolute differences between each consecutive pair of angles
    • Throw away all of the angles before the max difference
  • Average the remaining angles (average all point vectors then atan2 back into an angle)

Code

function process(points) {
    if(points.length === 0) { 
        txt = "Not enough points\n" + txt;
        return null; 
    }
    // compress points, removing those that are too close together
    var newPoints = [];
    newPoints.push(points[0]);
    for(var i = 1; i < points.length; i++) {
        if(Math.sqrt(Math.pow(points[i].x - newPoints[newPoints.length - 1].x, 2) + Math.pow(points[i].y - newPoints[newPoints.length - 1].y, 2)) > 5) {
            newPoints.push(points[i]);
        }
    }
    points = newPoints;
    if(points.length < 2) { 
        txt = "Not enough points\n" + txt;
        return null; 
    }
    // get all of the angles
    var angles = [];
    for(var i=0; i < points.length - 1; i++) {
        var rad = Math.atan2(points[i + 1].y - points[i].y, points[i + 1].x - points[i].x);
        angles[i] = rad;
        txt += "x: " + (points[i].x|0) + " y: " + (points[i].y|0) + " x: " + (points[i+1].x|0) + " y: " + (points[i+1].y|0) + " [" + ((rad * 180 / Math.PI)|0) + "]" + "\n";
    }
    txt += "\n";
    // get all of the diffs between angles
    // save the index of the max diff
    var absDiffs = [];
    var maxDiff = -1;
    var maxDiffAngleIndex = -1;
    for(var i=0; i < points.length - 1; i++) {
        var delta = Math.abs(angles[i] - angles[i + 1]);
        if(delta >= maxDiff) {
            maxDiff = delta;
            maxDiffAngleIndex = i + 1;
        }
    }
    if(maxDiffAngleIndex == -1) {
        txt = "Angle: " + angles[0] + " : " + (angles[0] * 180 / Math.PI) + "\n" + txt;
        return angles[0];
    } else if(maxDiffAngleIndex == angles.length - 1) {
        txt = "Angle: " + angles[angle.length - 1] + " : " + (angles[angles.length - 1] * 180 / Math.PI) + "\n" + txt;
        return angles[angles.length - 1];
    } else {
        // find the average angle from the index to the end
        var sumX = 0;
        var sumY = 0;
        for(var i = maxDiffAngleIndex; i < angles.length; i++) {
            sumX += Math.cos(angles[i]);
            sumY += Math.sin(angles[i]);
        }
        var avgX = sumX / (angles.length - maxDiffAngleIndex);
        var avgY = sumY / (angles.length - maxDiffAngleIndex);
        //
        var avgAngle = Math.atan2(avgY, avgX);
        txt = "Angle: " + avgAngle + " : " + (avgAngle * 180 / Math.PI) + "\n" + txt;
        return avgAngle;
    }
}

相关问答

更多

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)