Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/400.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 我应该如何调用3个函数以逐个执行它们?_Javascript_Asynchronous_Callback_Closures - Fatal编程技术网

Javascript 我应该如何调用3个函数以逐个执行它们?

Javascript 我应该如何调用3个函数以逐个执行它们?,javascript,asynchronous,callback,closures,Javascript,Asynchronous,Callback,Closures,如果我需要一个接一个地调用这个函数 $('#art1').animate({'width':'1000px'},1000); $('#art2').animate({'width':'1000px'},1000); $('#art3').animate({'width':'1000px'},1000); 我知道,在jQuery中,我可以执行以下操作: $('#art1').animate({'width':'1000px'},1000,'line

如果我需要一个接一个地调用这个函数

$('#art1').animate({'width':'1000px'},1000);        
$('#art2').animate({'width':'1000px'},1000);        
$('#art3').animate({'width':'1000px'},1000);        
我知道,在jQuery中,我可以执行以下操作:

$('#art1').animate({'width':'1000px'},1000,'linear',function(){
    $('#art2').animate({'width':'1000px'},1000,'linear',function(){
        $('#art3').animate({'width':'1000px'},1000);        
    });        
});        
async.waterfall([
  // A list of functions
  function(callback){
      // Function no. 1 in sequence
      callback(null, arg);
  },
  function(arg, callback){
      // Function no. 2 in sequence
      callback(null);
  }
],    
function(err, results){
   // Optional final callback will get results for all prior functions
});
但是,假设我没有使用jQuery,我想调用:

some_3secs_function(some_value);        
some_5secs_function(some_value);        
some_8secs_function(some_value);        
我应该如何调用这个函数来执行
一些3secs\u函数
,然后在调用结束后,执行
一些5secs\u函数
,然后在调用结束后,调用
一些8secs\u函数

更新:

这仍然不起作用:

(function(callback){
    $('#art1').animate({'width':'1000px'},1000);
    callback();
})((function(callback2){
    $('#art2').animate({'width':'1000px'},1000);
    callback2();
})(function(){
    $('#art3').animate({'width':'1000px'},1000);
}));
三个动画同时开始


我的错误在哪里?

因为您用javascript标记了它,所以我会使用计时器控件,因为您的函数名是3、5和8秒。因此,启动计时器,3秒后,第一次呼叫,5秒后第二次呼叫,8秒后第三次呼叫,完成后,停止计时器

通常在Javascript中,您所拥有的功能是正确的,因为函数正在一个接一个地运行,但由于看起来您正在尝试进行定时动画,因此计时器将是您的最佳选择。

在Javascript中,有同步和异步函数

同步函数 Javascript中的大多数函数都是同步的。如果要连续调用多个同步函数

doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
他们将按顺序执行<代码>doSomethingElse在
doSomething
完成之前不会启动
dosomethingusselfe这一次
,在
doSomethingElse
完成之前不会启动

异步函数 然而,异步函数不会互相等待。让我们看看上面的代码示例,这次假设函数是异步的

doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
这些函数将按顺序初始化,但它们将大致同时执行。你无法始终如一地预测哪一个将首先完成:恰好花费最短时间执行的一个将首先完成

但有时,您希望异步函数按顺序执行,有时您希望同步函数异步执行。幸运的是,这在回调和超时时都是可能的

回调 假设我们有三个异步函数要按顺序执行,
一些3secs函数
一些5secs函数
,以及
一些8secs函数

由于函数可以在Javascript中作为参数传递,因此可以将函数作为回调传递,以便在函数完成后执行

如果我们创建这样的函数

function some_3secs_function(value, callback){
  //do stuff
  callback();
}
然后您可以按顺序调用,如下所示:

some_3secs_function(some_value, function() {
  some_5secs_function(other_value, function() {
    some_8secs_function(third_value, function() {
      //All three functions have completed, in order.
    });
  });
});
超时 在Javascript中,您可以告诉函数在特定超时后执行(以毫秒为单位)。这实际上可以使同步函数异步运行

如果我们有三个同步函数,我们可以使用
setTimeout
函数异步执行它们

setTimeout(doSomething, 10);
setTimeout(doSomethingElse, 10);
setTimeout(doSomethingUsefulThisTime, 10);
然而,这有点丑陋,违反了法律。我们可以通过创建一个接受函数数组和超时的函数来解决这个问题

function executeAsynchronously(functions, timeout) {
  for(var i = 0; i < functions.length; i++) {
    setTimeout(functions[i], timeout);
  }
}

总之,如果您有要同步执行的异步函数,请使用回调;如果您有要异步执行的同步函数,请使用超时。

您的函数应该使用回调函数,该函数在完成时会被调用

function fone(callback){
...do something...
callback.apply(this,[]);

}

function ftwo(callback){
...do something...
callback.apply(this,[]);
}
然后,用法如下所示:

fone(function(){
  ftwo(function(){
   ..ftwo done...
  })
});
我不会在这里深入讨论setTimeout,但是:

  • 在本例中,我添加了要作为字符串执行的代码。这是将var传递给setTimeout函数的最简单方法,但纯粹主义者会抱怨
  • 也可以传递不带引号的函数名,但不能传递任何变量
  • 您的代码不会等待setTimeout触发
  • 一开始你很难理解这个问题:因为上一点,如果你从调用函数传递了一个变量,那么在超时触发时,这个变量就不再存在了——调用函数已经执行了,变量也消失了
  • 大家都知道我使用匿名函数来解决这些问题,但是有更好的方法

听起来您没有完全理解同步执行与异步执行之间的区别

更新中提供的代码会立即执行每个回调函数,而回调函数又会立即启动动画。但是,动画是异步执行的。它的工作原理如下:

some_3secs_function(some_value, function() {
  some_5secs_function(other_value, function() {
    some_8secs_function(third_value, function() {
      //All three functions have completed, in order.
    });
  });
});
  • 在动画中执行一个步骤
  • 使用包含下一动画步骤和延迟的函数调用
    setTimeout
  • 一段时间过去了
  • 执行给
    setTimeout
    的回调
  • 返回到步骤1
  • 这将一直持续到动画中的最后一步完成。同时,您的同步功能早已完成。换句话说,调用
    animate
    函数实际上并不需要3秒钟。通过延迟和回调来模拟这种影响

    您需要的是一个队列。在内部,jQuery对动画进行排队,仅在相应动画完成后执行回调。如果回调随后启动另一个动画,效果是它们按顺序执行

    在最简单的情况下,这相当于以下内容:

    window.setTimeout(function() {
        alert("!");
        // set another timeout once the first completes
        window.setTimeout(function() {
            alert("!!");
        }, 1000);
    }, 3000); // longer, but first
    
    这是一个通用的异步循环函数。它将按顺序调用给定的函数,在每个函数之间等待指定的秒数

    function loop() {
        var args = arguments;
        if (args.length <= 0)
            return;
        (function chain(i) {
            if (i >= args.length || typeof args[i] !== 'function')
                return;
            window.setTimeout(function() {
                args[i]();
                chain(i + 1);
            }, 2000);
        })(0);
    }    
    
    显然,您可以修改此选项,以占用可配置的等待时间,或立即执行第一个函数,或在链中的函数返回
    false
    时停止执行,或在指定上下文中应用
    函数,或使用
    ECM的JavaScript功能
    
    loop(
      function() { alert("sam"); }, 
      function() { alert("sue"); });
    
    Promise.resolve($('#art1').animate({ 'width': '1000px' }, 1000).promise()).then(function(){
        return Promise.resolve($('#art2').animate({ 'width': '1000px' }, 1000).promise());
    }).then(function(){
        return Promise.resolve($('#art3').animate({ 'width': '1000px' }, 1000).promise());
    });
    
    new Promise(function(fulfill, reject){
        //do something for 5 seconds
        fulfill(result);
    }).then(function(result){
        return new Promise(function(fulfill, reject){
            //do something for 5 seconds
            fulfill(result);
        });
    }).then(function(result){
        return new Promise(function(fulfill, reject){
            //do something for 8 seconds
            fulfill(result);
        });
    }).then(function(result){
        //do something with the result
    });
    
    async.waterfall([
      // A list of functions
      function(callback){
          // Function no. 1 in sequence
          callback(null, arg);
      },
      function(arg, callback){
          // Function no. 2 in sequence
          callback(null);
      }
    ],    
    function(err, results){
       // Optional final callback will get results for all prior functions
    });
    
        some_3secs_function(this.some_value).then(function(){
           some_5secs_function(this.some_other_value).then(function(){
              some_8secs_function(this.some_other_other_value);
           });
        });
    
        one(some_value).then(function(return_of_one){
           two(return_of_one).then(function(return_of_two){
              three(return_of_two);
           });
        });
    
    async function run(){    
        await $('#art1').animate({'width':'1000px'},1000,'linear').promise()
        await $('#art2').animate({'width':'1000px'},1000,'linear').promise()
        await $('#art3').animate({'width':'1000px'},1000,'linear').promise()
    }
    
    /*
        funcCond : function to call to check whether a condition is true
        readyAction : function to call when the condition was true
        checkInterval : interval to poll <optional>
        timeout : timeout until the setTimeout should stop polling (not 100% accurate. It was accurate enough for my code, but if you need exact milliseconds, please refrain from using Date <optional>
        timeoutfunc : function to call on timeout <optional>
    */
    function waitUntil(funcCond, readyAction, checkInterval, timeout, timeoutfunc) {
        if (checkInterval == null) {
            checkInterval = 100; // checkinterval of 100ms by default
        }
        var start = +new Date(); // use the + to convert it to a number immediatly
        if (timeout == null) {
            timeout = Number.POSITIVE_INFINITY; // no timeout by default
        }
        var checkFunc = function() {
            var end = +new Date(); // rough timeout estimations by default
    
            if (end-start > timeout) {
                if (timeoutfunc){ // if timeout function was defined
                    timeoutfunc(); // call timeout function
                }
            } else {
                if(funcCond()) { // if condition was met
                    readyAction(); // perform ready action function
                } else {
                    setTimeout(checkFunc, checkInterval); // else re-iterate
                }
            }
        };
        checkFunc(); // start check function initially
    };
    
    doSomething();
    waitUntil(function() { return doSomething_value===1;}, doSomethingElse);
    waitUntil(function() { return doSomethingElse_value===1;}, doSomethingUseful);