如何暂停一个函数的调用,直到另一个函数被独立调用?

问题描述 投票:0回答:3

我有下面的工作代码,但我觉得必须有一个更清洁的解决方案,我不认为承诺或回调将在我的情况下工作。

我有一个主函数(foo)在x毫秒后独立调用自身(在我的实际代码中,它重复执行此操作)。当它自己调用时,它会增加存储在对象中的值。

我有第二个功能(bar),偶尔随机调用。但是,我希望(在某些情况下)能够暂停执行此功能,直到下次再次调用主函数(foo)为止。

在下面的工作示例中,bar在调用prop时存储bar的当前值,然后反复检查prop的值,直到值发生变化。当值不再是==时,bar执行else中的代码。如果bar只是简单地听prop改变(或foo被调用),并且在那一刻被执行,那么它的工作原理但不干净且时间不准确。

我不相信承诺或回调会起作用,因为它们通常用于第二个函数作为参数传递的情况。在我的情况下,我的第二个功能是另一个工作,并且已经重复做了自己的工作。我也不希望再次执行第二个函数,我只是希望它的调用允许函数1完成自己的执行。

使用延迟对我的实际情况也不理想。

更多详情

我的实际程序通过随机触发音频文件来播放音乐。 bar()是确定播放声音的所有方式/属性的功能(持续时间,音量,淡入/淡出等)。

foo()是一个主函数,用于确定程序所在歌曲的哪个部分。因此,每次调用foo()时,它都会增加程序/歌曲所处的阶段(即1,2,3,4),它也会调用功能的数量,更新属性,改变如何允许get()功能播放声音。

所以,该程序主要是随机播放声音(就像没有严格的节拍/小节),我想在某些情况下可以选择在条形上播放它们。由于foo()是跟踪这个时间的功能,我已经为get()增加了功能,这样当一个节拍没有触发声音时,它会延迟直到指定的节拍发生然后被允许播放。我有这个功能。

当声音被分配到已经过去的节拍上时,诀窍就出现了。在这些情况下,我需要暂停get()直到下一个柱(即,当再次调用foo()时)。在正常的音乐案例中,时间(每分钟节拍数)将被修复,这样我就可以简单地进行数学计算并将其设置为setTimeout直到正确的时间。但是,我的程序有点非传统,并且每次调用foo()时持续时间都会发生变化。因此,提前知道下一个柱的持续时间。

因此,总而言之,bar()(声音)被调用,它存储了一大堆参数,用于确定声音的播放方式。我需要bar()在调用之后暂停,直到它听到/看到foo()再次被调用,然后才完成播放声音的工作。

这是我的工作范例。

const config = {
  object: {
    prop: 1
  },
};

(function foo() {
  setTimeout(function() {
    config.object.prop = 3;
    console.log('foo changed the value of config.object.prop');
  }, 4000);
})();

bar();

function bar() {

  var prop = config.object.prop;

  (function nar() {
    if (prop == config.object.prop) {
      console.log('sorry, still waiting for config.object.prop to change');
      setTimeout(function() {
        nar();
      }, 1000);
    } else {
      console.log('Executed only after config.object.prop changed!!!');
    }
  })();
}
javascript promise callback
3个回答
1
投票

这是回调和观察者模式的完美用例。

您的主进程应该生成节拍事件,并触发等待它们的函数。

您可以使用一个框架来帮助您解决这个问题,或者您甚至可以使用一个函数来承担主进程发生的下一个节拍,但是一个自行开发的解决方案也可以工作。你需要的只是一个监听器函数数组,bar将该功能的节拍部分添加到该列表中,foo调用(并删除)该列表中的函数。


0
投票

你可以有一个布尔来决定每次执行foo()时是否应该调用nar(),并且当函数需要运行时让bar()将Boolean设置为true。

let runNar = false;

(function foo() {
  setTimeout(function() {
	if (runNar === true) {
		nar();
		runNar = false;
	}
    console.log('foo changed the value of config.object.prop');
  }, 4000);
})();

bar();

function bar() {
	runNar = true;
};

function nar() {
	console.log('Excuted when foo() is called');
};

0
投票

它也可以使用Promises来解决,但我认为有更好的解决方案: 使用setters或Proxy

How does it work?

  • 二传手: setter可以定义伪属性,但不能有值,但是如果你尝试设置该属性的值,则会调用一个函数,接收新值作为参数。

句法:

var obj={
  prop:1,
  set anotherProp(value){
    //Handle set:
    this.prop=value
  }
}
obj.anotherProp=5
obj.prop //5

翻译成你的情况:

const config = {
  object: {
    prop: 1,
    set setterProp(value){
      this.prop=value;
      bar()
    }
  },
};

(function foo() {
  setTimeout(function() {
    console.log('foo changed the value of config.object.prop');
    config.object.setterProp = 3;
  }, 4000);
})();

function bar() {
    console.log('Executed only after config.object.prop changed!!!');
}
  • 代理:使用代理对象,您可以执行诸如setter之类的操作,但是: 代理可用于监视和控制对象的任何操作(获取,设置,删除,函数调用,类构造等) 与setter不同,Proxy监视对象的所有属性。

句法:

var obj={
  prop:1
}
var proxy=new Proxy(obj,{
  set:function(obj,prop,value){
    //Handle set:
    obj[prop]=value;
  }
})
proxy.prop=5
proxy.prop //5
obj.prop   //5

翻译成你的情况:

const config = {
  object: {
    prop: 1
  },
};
const proxy=new Proxy(config.object, {
  set: function(obj,prop,value){
    //Handle set:
    obj[prop]=value;
    if(prop==='prop'){bar()};
  }
});
(function foo() {
  setTimeout(function() {
    console.log('foo changed the value of config.object.prop');
    proxy.prop = 3;
  }, 4000);
})();

function bar(){
  console.log('Executed only after config.object.prop changed!!!');
}

Ok, but what if I don't want to call bar everytime!

const barList=[]
const config = {
  object: {
    prop: 1
  },
};
const proxy=new Proxy(config.object, {
  set: function(obj,prop,value){
    //Handle set:
    obj[prop]=value;
    if(prop==='prop'){
      barList.filter(x=>{
        bar(...x)
        return false
      })
    };
  }
});
(function foo() {
  setTimeout(function() {
    console.log('foo changed the value of config.object.prop');
    proxy.prop = 3;
  }, 4000);
})();
function callBar(...args){
  barList.push(args)
}
function bar(...argument){
  console.log('Executed only after config.object.prop changed!!!', ...argument);
}
callBar();
callBar('with','some','arguments');
© www.soinside.com 2019 - 2024. All rights reserved.