下面有可用的代码,但是我觉得必须有一个更干净的解决方案,而且我认为promise或callback不能在我的情况下起作用。
我有一个主函数(foo),它会在x毫秒后独立调用自身(在我的实际代码中,它会重复执行此操作)。调用自身时,它将增加存储在对象中的值。
我有第二个函数(栏),有时会随机调用。但是,我希望(在某些情况下)能够暂停该函数的执行,直到下次再次调用主函数(foo)为止。
在下面的工作示例中,bar
会在调用prop
时存储bar
的当前值,然后不断重复检查prop
的值,直到值更改为止。当值不再==时,bar
执行else
中的代码。这是可行的,但并不干净,而且计时不如bar
仅听prop
进行更改(或调用foo
并执行)时的准确性在那一刻。
我不认为promise或callback会起作用,因为它们通常在将第二个函数作为参数传递的情况下使用。就我而言,我的第二个职能是拥有另一项工作,并且已经在重复做自己的工作。我也不想再次执行第二个函数,只希望调用它允许一个函数完成自己的执行。
对于我的实际情况,使用延迟也不理想。
更多详细信息
我的实际程序通过随机触发音频文件播放来制作音乐。 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!!!');
}
})();
}
答案 0 :(得分:1)
这是回调和观察者模式的完美用例。
您的主进程应产生拍子事件,并触发等待它们的函数。
您可以使用用于消息总线的框架来帮助您解决此问题,或者甚至可以使用可以保证主过程中发生下一个节拍的函数,但是本地解决方案也可以使用。您所需要的只是一系列侦听器功能,bar
将功能的节拍部分添加到该列表中,然后foo
调用(并从该列表中删除)这些功能。
答案 1 :(得分:0)
您可以使用一个布尔值来决定是否应在每次执行foo()时调用nar(),并在需要运行该函数时让bar()将布尔值设置为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');
};
答案 2 :(得分:0)
也可以使用Promises来解决,但我认为有更好的解决方案:
使用setter
或Proxy
!
语法:
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!!!');
}
语法:
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!!!');
}
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');