Javascript承诺然后在类中



我正在努力理解Promises是如何工作的,但我无法让我的代码工作。

class Lights {
constructor(delay) {
this.blue = 0;
this.green = 0;
this.red = 0;
this.delay = delay;
}
fadeIn(color, i) {
var self = this;
return new Promise(function(resolve, reject) {
setTimeout(function () {
self[color] = i;
console.log(self[color]);
i+=5;
if (i <= 255) {
self.fadeIn(color, i);
}
resolve(self);
}, self.delay);
});
}
fadeOut(color, i) {
var self = this;
return new Promise(function(resolve, reject) {
setTimeout(function () {
self[color] = i;
console.log(self[color]);
i-=5;
if (i >= 0) {
self.fadeIn(color, i);
}
resolve(self);
}, self.delay);
});
}
}

var lights = new Lights(50);
lights.fadeIn("blue", 0).then(
lights.fadeOut("blue", 255)
);

下面是代码的jsFiddle。

代码背后的思想是将蓝色从0设置为255,将Then从255设置为0。我该怎么做?

您正在进行递归调用,因此在最后一次调用中,您解析的不是您调用then的第一个promise中的解析,因此您可以将第一个解析存储在类中的一个属性中,然后再调用它。

class Lights {
constructor(delay) {
this.blue = 0;
this.green = 0;
this.red = 0;
this.delay = delay;
this.fadeInResolve = null;
this.fadeOutResolve = null;
}
fadeIn(color, i) {
return new Promise((resolve, reject) => {
if (!this.fadeInResolve) {
this.fadeInResolve = resolve
}
setTimeout(() => {
this[color] = i;
console.log(this[color]);
i += 5;
if (i <= 255) this.fadeIn(color, i);
else this.fadeInResolve(this)
}, this.delay);
});
}
fadeOut(color, i) {
return new Promise((resolve, reject) => {
if (!this.fadeOutResolve) {
this.fadeOutResolve = resolve
}
setTimeout(() => {
this[color] = i;
console.log(this[color]);
i -= 5;
if (i >= 0) this.fadeOut(color, i);
else this.fadeOutResolve(this)
}, this.delay);
});
}
}
var lights = new Lights(50);
lights.fadeIn("blue", 0).then(() => {
console.log('Fade in done')
lights.fadeOut("blue", 255).then(() => {
console.log('Fade out done')
})
});

Promise.prototype.then()应该采用回调函数,并且递归不会等待。考虑一下这个代码,它可以用来做同样的事情:

//promisify :)
function timer(delay) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();
}, delay);
});
}
class _Modulator {
constructor(_resolution = 255, _delay = 5) {
/* assert resolution and delay > 0; */
this._resolution = _resolution;
this._delay = _delay;
this._counter = 0;
this._running = false;
}
start() {
console.log("timer start");
this._running = true;
this._start();
}
_start() {
return timer(this._delay).then(() => {
if (this._running === true) {
this._counter += 1;
console.log("tick");
this._onTick();
/* care should be taken to ensure this will always catch, e.g., 
* correcting init
*/
if (this._counter === this._resolution) {
this._counter = 0;
this._onCycle();
}
this._start();
}
});
}
stop() {
this._running = false;
console.log("timer stopped");
}
_onTick() {
console.log("tick handle: %s", this._counter);
}
_onCycle() {
console.log("new cycle");
}
}
class UpDownModulator extends _Modulator {
constructor(_resolution = 255, _delay = 5) {
super(_resolution, _delay);
this._dir = 1;
}
_onTick() {
console.log("tick handle: %s", this.getCounter());
}
_onCycle() {
this._toggleDirection();
console.log("new cycle: going %s", this.getDirection());
}
_toggleDirection() {
this._dir ^= 1; 
}
getCounter() {
return this._dir
? this._counter
: this._resolution - this._counter;
}
getDirection() {
return this._dir ? "up" : "down";
}
}
let c = new UpDownModulator();
c.start();

你可以创建一个依赖于调制器的ColorFader类并观察它。这会创建符合SRP的干净抽象。

我希望这能有所帮助!

最新更新