我有下面的工作代码,但我觉得必须有一个更清洁的解决方案,我不认为承诺或回调将在我的情况下工作。
我有一个主函数(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!!!');
}
})();
}
这是回调和观察者模式的完美用例。
您的主进程应该生成节拍事件,并触发等待它们的函数。
您可以使用一个框架来帮助您解决这个问题,或者您甚至可以使用一个函数来承担主进程发生的下一个节拍,但是一个自行开发的解决方案也可以工作。你需要的只是一个监听器函数数组,bar
将该功能的节拍部分添加到该列表中,foo
调用(并删除)该列表中的函数。
你可以有一个布尔来决定每次执行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');
};
它也可以使用Promises来解决,但我认为有更好的解决方案:
使用setter
s或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');