承诺设计模式
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了承诺设计模式相关的知识,希望对你有一定的参考价值。
我已经创建了一个SoundManager
来处理我的应用程序中的声音。在我的应用程序中,我实例化一个SoundManager
,然后使用它来加载音频文件,并在加载后返回一个承诺。
我省略了一些代码,因为我认为在这种情况下不重要 - 我知道它们都正确加载,例如,我的应用程序中的then()
函数,它从loadSounds()
传递的Promises数组接收一个对象所有的声音(不是承诺)。
但是,如果从我的应用程序(在声音全部加载的位置),我调用playSound()
,this.sounds
变量将是一个Promises数组。
为什么会这样?一旦承诺得以实现,this.sounds
中的变量SoundManager
不应更新吗?
这也不是一个好的模式,所以有关如何实现这一点的任何想法?
import Promise from 'bluebird';
import {Howl, Howler} from 'howler';
export default class SoundManager {
constructor(){
this.sounds;
}
loadSounds(soundsArray){
this.sounds = soundsArray.map((data) => {
return new Promise((resolve, reject) => {
// ...
})
})
return Promise.all(this.sounds)
}
playSound(id){
console.log('this.sounds: ', this.sounds); //this is an array of promises, when I expect an array of sound objects
let sound = this.sounds.filter((sound) => sound.id === id);
if (!sound.length) {
console.warn(`could not find sound with id "${id}"`)
return false;
}
sound[0].play()
}
}
this.sounds
包含一系列承诺,因为这正是你在这里指定的:
loadSounds(soundsArray){
this.sounds = soundsArray.map((data) => {
return new Promise((resolve, reject) => {
// ...
})
})
return Promise.all(this.sounds)
}
你的soundsArray.map()
的结果是一系列的承诺。
如果您希望它包含最终值,您可以这样做:
loadSounds(soundsArray){
let sounds = soundsArray.map((data) => {
return new Promise((resolve, reject) => {
// ...
})
})
return Promise.all(sounds).then(data => {
this.sounds = data;
return data;
});
}
虽然这样做似乎有点问题,因为除了使用loadSounds()
返回的承诺之外,没有其他方法可以知道this.sounds
何时包含您想要的数据。因此,如果知道数据何时存在的唯一方法是loadSounds()
返回的承诺,则不清楚其他代码如何能够可靠地使用this.sounds
。
您可以在Promise.all()
中存储来自this.sounds
的承诺,然后任何想要声音的代码都可以使用this.sounds.then()
来获取它。我们必须看到更多你正在尝试用this.sounds
做什么,当你想要做的时候才知道最好的设计是什么。
一旦履行承诺,SoundManager中的变量
this.sounds
不应该更新吗?
不,这不是承诺的工作方式。他们保留承诺对象,他们不会“成为”他们所实现的价值。
这看起来不是一个好模式
是的,不要在管理器中加载声音。经理可能会或可能不会在其生命周期内使用 - 这不是特别有用。只有在加载声音后才能更好地实例化 - 请参阅this also here。
export default class SoundManager {
constructor(sounds) {
this.sounds = sounds;
}
static loadAndCreate(soundsArray) {
return Promise.all(soundsArray.map((data) => {
return new Promise((resolve, reject) => {
…
})
})).then(sounds => new this(sounds));
}
playSound(id){
console.log('this.sounds: ', this.sounds); //this is always an array of sound objects
let sound = this.sounds.find(sound => sound.id === id);
if (!sound) {
console.warn(`could not find sound with id "${id}"`)
return false;
}
sound.play()
}
}
以上是关于承诺设计模式的主要内容,如果未能解决你的问题,请参考以下文章
如果一个已经在运行的 PromiseKit 承诺返回一个未决的承诺的最佳 Swift 模式是啥?