JavaScript: 在另一个延迟函数内调用延迟函数

4
所以,我有一个被称为delayed1的延迟函数,每当cond1为真时就会重复调用它,问题是,在delayed1函数内部的某个地方,如果cond3为真,则会调用另一个被称为delayed2的延迟函数。 现在的问题是,我希望delayed1等待直到delayed2完成(也就是直到cond2为假),然后再恢复执行,但似乎并没有发生这种情况。一旦delayed2开始运行,delayed1就不会等待它完成然后再恢复执行。有什么办法可以解决这个问题吗?希望我表述得足够清楚...
function delayed2() {
    setTimeout(function () {
       do_something2();
        if ( cond2 ) {
            delayed2();
        }
    }, 1000)
}

function do_something1(){
    if ( cond3 ){
        delayed2();
    }
    else {
        something_else();
    }
}

function delayed1() {
    does_something_here();
    setTimeout(function () {
        do_something1();
        if ( cond1 ){
            delayed1();
        }
    }, 1000)

}

我昨天开始学习JS,但我知道编程的基础 :) 我不确定stacksnippets是否可用,因为我正在通过Tampermonkey在某个网站上使用此代码。 - Pred
你想每秒钟重复运行do_something2、do_something_here和do_something1吗? - Jaromanda X
自动纠错很烦人。 - Jaromanda X
@JaromandaX,“Autocucumber”是什么? - guest271314
@JaromandaX,那是正确的。 - Pred
显示剩余4条评论
3个回答

3
我明白你在尝试做什么。你可能想用不同的方法来解决问题。最好的方法是使用promisesDeferreds
这里是使用jquery deferreds的示例代码。
var wait_a_second = $.Deffered();

$.when(wait_a_second)
    .then(does_something_here)
    .then(function(){
        if( cond1 ) delayed1();
    })

    .then(delayed1);


function delayed1(){
    var d = $.Deffered()

    // Your conditions and logic
    if( cond ) {
        d.resolve();
    }

    return d.promise();
}

function delayed2(){
    var d = $.Deffered();

    // Your conditions and logic
    if( cond ) {
        d.resolve();
    }

    return d.promise();
}

简而言之,学习Promise来管理异步操作队列。

2
你应该使用 Promise 在 JavaScript 中实现同步执行。
Promise 是一种机制,它返回一个对象,你可以将回调函数挂钩到这个对象上。这些回调函数可以在特定函数完成执行后被调用。下面是它如何适用于你的情况。
通常你有三个相互依赖的函数。第一个应该等待第二个,第二个应该等待第三个。在第一层中,第二个函数应该返回一个 Promise。
function delayed1() {

    does_something_here();

    setTimeout(function () {
        var promise = do_something1();

        promise.then(function(){
            if ( cond1 ){
               delayed1();
           }
        });

    }, 1000) 
}

这是您的第二个函数。它创建并返回一个 Promise 对象。在其 if (cond3) 中,它还应该等待来自第三个函数的 Promise 对象。我不会为您编写第三个函数,但我相信您可以按照这种模式自己完成它。
function do_something1(){

   return new Promise(function(resolve){
       if ( cond3 ){
           var promise = delayed(2);

           promise.then(function(){ 
              resolve()
            }) 

       }
       else {
          something_else();
          resolve();
       }    
   })  


}

所以如果我理解正确的话,我需要从第三个函数(在这种情况下称为delayed2())返回另一个promise,这样就可以解决问题了,对吗? - Pred
这样不应该做点什么吗?https://jsfiddle.net/7esybcu9/ 我知道我在某个地方做错了,我在网上搜索了 Promise,但就是找不到一种让它们在我的特定情况下工作的方法。抱歉。 - Pred
дҪ жңүдёӨдёӘй—®йўҳгҖӮдёҖдёӘжҳҜдҪ жІЎжңүиҝҗиЎҢд»»дҪ•еҮҪж•°гҖӮеңЁ delayed1 еҮҪж•°еҗҺйқўеҠ дёҠ ()гҖӮеҸҰдёҖдёӘй—®йўҳжҳҜ delayed2 еҮҪж•°жІЎжңүи§ЈеҶід»»дҪ•й—®йўҳгҖӮеӣ жӯӨпјҢеңЁ do_something1 дёӯпјҢpromise.then ж°ёиҝңдёҚдјҡжү§иЎҢгҖӮд»ҺеӨҙејҖе§ӢеӯҰд№  Promise ж•ҷзЁӢпјҲMDNпјүпјҢеҒҡдёҖдәӣз®ҖеҚ•зҡ„зӨәдҫӢгҖӮ然еҗҺдёәдёӨдёӘзә§еҲ«жһ„е»әдҪ зҡ„жЎҲдҫӢгҖӮеҪ“дҪ еҜ№дәҢзә§жһ¶жһ„жңүдәҶеҫҲеҘҪзҡ„зҗҶи§Јж—¶пјҢеҶҚеҺ»е°қиҜ•з¬¬дёүзә§гҖӮ - Charlie

1
您可以尝试使用回调函数。以下是一个基本的示例表示:

var count = 0;

function delay1(callback) {
  setTimeout(function() {
    console.log("Delay 1");
    count++;
    if (count < 12) {
      if (count % 2 == 0) {
        delay1();
      } else {
        delay2()
      }
    }
    if (callback) {
      callback();
    }
  }, 1000);
}

function delay2(callback) {
  setTimeout(function() {
    console.log("Delay 2");

    if (count > 10) {
      delay1(function() {
        console.log("This is callback;")
      })
    } else if (count % 2 == 0) {
      delay2();
    } else {
      delay1()
    }

    if (callback) {
      callback();
    }
    count++;
  }, 1000);
}


delay1();


我在尝试过 Promise 和 Deferred(不成功)后,将这个作为最后的选择,它完全按照我的期望工作了,非常感谢!现在如果你不像我这样是个新手,我建议使用另外两种解决方案,因为它们更受推荐,我也需要学习使用它们,但目前我只需要一个快速的解决方法来解决这个问题。再次感谢您的答案。 - Pred
我很高兴能够帮助。或许我说错了,但promises的发明是因为一种被称为“回调地狱”(callback hell)的情况。你可以参考callbackhellSO - Post - Rajesh
1
当然。Promises提供了一种易于使用、简短而新颖的机制,可以用来完成您在此处使用回调函数所做的操作。 - Charlie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接