Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 实现一个遍历数组的运行程序_Javascript_Jquery_Asynchronous - Fatal编程技术网

Javascript 实现一个遍历数组的运行程序

Javascript 实现一个遍历数组的运行程序,javascript,jquery,asynchronous,Javascript,Jquery,Asynchronous,粗体表示更新 我有一个数组,steps,它的内容是带有动作和元素的对象。像这样: steps = [{action: 'click', element: <jQuery element>}, {action: 'click', element: <jQuery element>}, ., ., N] 注意,在上面的示例中,steps只是jquery对象的数组。它还没有达到所需的格式: steps = [{action: 'click', elemen

粗体表示更新

我有一个数组,
steps
,它的内容是带有动作和元素的对象。像这样:

steps = [{action: 'click', element: <jQuery element>}, 
         {action: 'click', element: <jQuery element>}, ., ., N]
注意,在上面的示例中,
steps
只是jquery对象的数组。它还没有达到所需的格式:

steps = [{action: 'click', element: <jQuery element>}, 
         {action: 'click', element: <jQuery element>}, ., ., N]
steps=[{action:'click',element:},
{操作:'click',元素:},,,N]
我需要遵循的“模式”是什么?我需要使用延迟对象来处理这个问题吗?它是用setTimeout、setInterval实现的吗?谢谢

最终实施

var run = function(steps, interval, timeout) {
    var timer,
        time = 0,
        i = 0;

    runSingle(steps[0]);

    function abort() {
        console.log("Run aborted");
    }

    function runSingle(step) {
        timer = setInterval(function() {
            time += interval;
            if ($(step.element).is(':visible') === true) {
                clearInterval(timer);
                time = 0;
                $(step.element).trigger(step.action);
                (i < (steps.length - 1)) && runSingle(steps[++i]);
            } else if (time >= timeout) {
                clearInterval(timer);
                abort();
            }
        }, interval);
        console.log("Performed: ", step.action, "on", step.element) 
        if (i === (steps.length - 1)) console.log("Run successful");
    }
}
var run=function(步骤、间隔、超时){
var定时器,
时间=0,
i=0;
runSingle(步骤[0]);
函数中止(){
日志(“运行中止”);
}
函数runSingle(步骤){
计时器=设置间隔(函数(){
时间+=间隔;
if($(step.element).is(':visible')==true){
清除间隔(计时器);
时间=0;
$(step.element).trigger(step.action);
(i<(步骤长度-1))&运行单个步骤[++i];
}否则如果(时间>=超时){
清除间隔(计时器);
中止();
}
},间隔);
日志(“已执行:”,step.action,“on”,step.element)
if(i==(steps.length-1))console.log(“运行成功”);
}
}

首先,请注意,在您的示例中,
v
变量将表示数组中的一个对象,因此说
v.click()
$(v).is(':visible')
-您应该说
v.element.click()
v.element.is(':visible')

如果您的意思是
action
将是一个字符串,它是jQuery方法的名称,
element
是一个jQuery对象,那么您可以这样做:

$.each(steps, function(i, obj) { 
    obj.element[obj.action]();
});
var run = function(steps, delay, timeout) {
             var i = 0,
                 nextStep = function() {
                    if (i < steps.length) {
                       var step = steps[i],
                           retryDelay = 25,
                           retryTotal = 0,
                           intervalId = setInterval(function() {
                              retryTotal += retryDelay;
                              var $el = $(step.element);
                              if ($el.is(':visible')) { 
                                $el[step.action](); 
                                clearInterval(intervalId);
                                i++;
                                setTimeout(nextStep, delay);
                              } else if (retryTotal >= timeout) {
                                clearInterval(intervalId);
                              }
                           }, retryDelay);
                    };
                 }
             nextStep();
};

run(steps, 50, 3000);
如果
element
是一个字符串,表示应用于创建jQuery对象的选择器,则:

$.each(steps, function(i, obj) { 
    $(obj.element)[obj.action]();
});
您不需要引入轮询概念,除非
操作
可能会异步执行某些操作,例如,如果它进行淡入,或者通过Ajax添加元素

在您的示例中,对于是否继续当前步骤,您似乎应用的唯一标准是当前元素是否可见。如果是这种情况,您可以这样做:

$.each(steps, function(i, obj) { 
    obj.element[obj.action]();
});
var run = function(steps, delay, timeout) {
             var i = 0,
                 nextStep = function() {
                    if (i < steps.length) {
                       var step = steps[i],
                           retryDelay = 25,
                           retryTotal = 0,
                           intervalId = setInterval(function() {
                              retryTotal += retryDelay;
                              var $el = $(step.element);
                              if ($el.is(':visible')) { 
                                $el[step.action](); 
                                clearInterval(intervalId);
                                i++;
                                setTimeout(nextStep, delay);
                              } else if (retryTotal >= timeout) {
                                clearInterval(intervalId);
                              }
                           }, retryDelay);
                    };
                 }
             nextStep();
};

run(steps, 50, 3000);
var run=函数(步骤、延迟、超时){
var i=0,
下一步=函数(){
如果(i<步长长度){
var步骤=步骤[i],
retryDelay=25,
retryTotal=0,
intervalId=setInterval(函数(){
retryTotal+=retryDelay;
var$el=$(步骤元素);
如果($el.is(':visible'){
$el[步骤行动]();
clearInterval(intervalId);
i++;
设置超时(下一步,延迟);
}否则如果(retryTotal>=超时){
clearInterval(intervalId);
}
},retryDelay);
};
}
下一步();
};
运行(步骤503000);
run()
函数定义了一个
nextStep()
函数,该函数使用
setInterval
不断检查当前元素是否可见。一旦完成,它将执行该操作,清除间隔,并通过
setTimeout
调用自身来移动到下一个元素


我不确定如何将超时概念与轮询结合起来,因为如果当前元素在指定的时间后不可见,您会怎么做?您不能真正继续下一个元素,因为它也可能依赖于前面的步骤。我想您可以通过清除间隔而不再调用
nextStep()
来中止整个过程编辑:我已经更新了代码,以便按照最后一句话工作。

这里有一些东西。我没有彻底测试它:

var run = function(steps, interval)
{
    var timer,
        time = 0, timeout = 10000,
        ciel = steps.length - 1,
        i = 0;

    run_single(steps[0]);

    function run_single(item)
    {
        timer = setInterval(function()
        {
            var $el = $(item.selector);

            time += interval;

            if ( $el.length )
            {
                clearInterval( timer );
                time = 0;

                $el.trigger( item.action );

                i < ciel && run_single( step[ ++i ] );
            }
            else
            {
                if ( time >= timeout ) clearInterval( timer );
            }

        }, interval);
    }
};

var steps = [
    {action: 'click', selector: '#first'},
    {action: 'hover', selector: '#second'},
    {action: 'change', selector: '#third'}
    // and so on...
];

run(steps, 100);
var run=函数(步骤、间隔)
{
var定时器,
时间=0,超时=10000,
ciel=步长。长度-1,
i=0;
单次运行(步骤[0]);
单个功能运行(项目)
{
计时器=设置间隔(函数()
{
var$el=$(item.selector);
时间+=间隔;
如果($el.length)
{
清除间隔(计时器);
时间=0;
$el.触发器(项目.操作);
i=超时)清除间隔(计时器);
}
},间隔);
}
};
变量步骤=[
{操作:'click',选择器:'#first'},
{操作:'hover',选择器:'#second'},
{操作:'change',选择器:'#third'}
//等等。。。
];
运行(步骤100);

请参见此处的操作:

表示jQuery对象,还是仅表示用作jQuery选择器的CSS选择器?如果它已经是jQuery对象,那么在向DOM添加新元素时它不会更新……谢谢。当前它是一个jqueryobject,我必须更新它才能使用选择器。如果您的选择器是一个类选择器,并且页面上已经有其他元素与该类一起使用,您如何知道前面的函数是否已经完成了它的工作?抱歉。我应该更清楚地说明,单击任何元素都可以通过ajax创建dom元素。我将更新这篇文章。另外,为了澄清这个问题,“如果当前元素在指定的时间之后不可见,那么