如何设置与目标函数调用相同的回调顺序调用 [英] How to set callback order invocation same as target function invocation

查看:100
本文介绍了如何设置与目标函数调用相同的回调顺序调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目有问题.

为了描述这个问题,我编写了简化的代码段:

To describe this issue I have wrote simplified code snippet:

function waitFor(fnReady, fnCallback) {
    var check = function() {
        if (fnReady()) {
            fnCallback();
        }
        else {
            setTimeout(check, 100);  // wait another 100ms, and try again
        }
    };

    check();
}


var result = 0;
var flag = true;
function ajaxRequest() {
    setTimeout(
         function() { flag = false; 
                     console.log('ping');
                    },3000
    );
}

function ajaxRequestHandler() {
    setTimeout(
         function() { flag = true; 
                      console.log('pong');
                    }, 200
    );
}
for(var i =0;i<10; i++){   
    waitFor(function() { return flag; }, ajaxRequest);
    waitFor(function() { return !flag; }, ajaxRequestHandler);
}

它返回:

ping - 10 times
pong - 10 times

所需结果:

ping 
3 second timeout 
ping
---------------------
ping
3 second timeout 
pong
--------------------
.....

您能帮我更正我的代码吗?

Can you help correct my code?

实际问题:

我有一张Google地图.
我应该重绘很多地方.

I have a google map.
I have a lot of places when I should to redraw it.

对于应用程序逻辑,如果我发送

For application logic very important that If I send

request1
request2
request3
request4

我应该按此顺序处理回复

I should handle responses in the this order

handle response of request1
handle response of request2
handle response of request3
handle response of request4 

我不知道请求顺序的问题.

Problem that I don't know order of requests.

在文件的不同位置,我看到以下代码行:

In different places of file I see following code rows:

google.maps.event.addListener(searchBox, 'bounds_changed', renderTerminalsOnMapAndFitBounds);
...
$.getJSON('getAllTerminals.json', renderTerminalsOnMapAndFitBounds);
.....
$.getJSON('getAllTerminalsInsideRectangle.json', renderTerminalsOnMapAndFitBounds);
...
$.getJSON('getAllTerminalsInsideCircle.json', renderTerminalsOnMapAndFitBounds);
...
$.getJSON('getBigTerminals.json', renderTerminalsOnMapAndFitBounds);
........

renderTerminalsOnMapAndFitBounds方法将请求发送到服务器,并成功在地图上替换呈现结果.但是这个事件经常发生

renderTerminalsOnMapAndFitBounds method sends request to server and in succes alternative render result on map. But this event happens very often

推荐答案

我个人会使用promise,但是您说的没有promise(不确定原因),因此这是普通javascript中的通用音序器算法(已在链接下面的jsFiddle):

I personally would use promises for this, but you've said no promises (not sure why), so here's a generic sequencer algorithm in plain javascript (tested in the jsFiddle linked below):

function sequence(fn) {
    // initialize sequence data upon first use
    if (typeof sequence.low === "undefined") {
        sequence.low = sequence.high = 0;
        sequence.results = {};
    }
    // save id in local variable so we can reference it in the closure from the function below
    var id = sequence.high;

    // advance to next sequence number
    ++sequence.high;

    // initialize the result value for this sequence callback
    sequence.results[id] = {fn: fn, args: [], ready: false, context: null};

    return function(/* args */) {
        // save args and context and mark it ready
        var args = Array.prototype.slice.call(arguments, 0);
        // get the results object for this callback and save info in it
        var thisResult = sequence.results[id];
        thisResult.args = args;
        thisResult.context = this;
        thisResult.ready = true;

        // now process any requests in order that are ready
        for (var i = sequence.low; i < sequence.high; i++) {
            var result = sequence.results[i];
            // if this one is ready, process it
            if (result.ready) {
                // increment counter past this result
                ++sequence.low;
                // remove this stored result
                delete sequence.results[i];
                // process this result
                result.fn.apply(result.context, result.args);
            } else {
                // if this one not ready, then nothing to do yet
                break;
            }
        }
    };
}

// your usage:

google.maps.event.addListener(searchBox, 'bounds_changed', sequence(renderTerminalsOnMapAndFitBounds));
...
$.getJSON('getAllTerminals.json', sequence(renderTerminalsOnMapAndFitBounds));
.....
$.getJSON('getAllTerminalsInsideRectangle.json', sequence(renderTerminalsOnMapAndFitBounds));
...
$.getJSON('getAllTerminalsInsideCircle.json', sequence(renderTerminalsOnMapAndFitBounds));
...
$.getJSON('getBigTerminals.json', sequence(renderTerminalsOnMapAndFitBounds));
........

正在运行的演示: http://jsfiddle.net/jfriend00/aqugm1fs/

从概念上讲,其作用如下:

Conceptually, what this does is as follows:

  1. 传递一个替代完成处理程序代替正常的完成回调.
  2. 此替代函数使用序列ID标记每个响应,并保存了原始的完成处理程序.
  3. 如果一个响应返回时,另一个序列号较低的响应仍在等待处理,则结果将被存储并保存以备后用.
  4. 每个响应进入时,它会按顺序处理尽可能多的响应

注意:虽然所有示例都使用相同的回调函数,但该函数可与任何回调函数一起使用,因此可以混合使用不同类型的操作.

Note: while all the examples you have use the same callback function, this will work with any callback function so it would work with a mix of different types of operations.

这篇关于如何设置与目标函数调用相同的回调顺序调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆