为什么链中的所有方法同时执行?
Why all methods in chain executed at the same time?
为什么链中的所有方法同时执行?我将方法包装在 setTimeout 中。我做错了什么?
我知道如何使用 promise 来做到这一点,但我正在学习链接技术。
const delay = function delay(func) {
return function(...args) {
setTimeout(() => {
return func.apply(this, [...args]);
}, 2000);
return this;
};
}
class TimePopup {
constructor() {
this.firstMethod = delay(this.firstMethod);
this.secondMethod = delay(this.secondMethod);
this.thirdMethod = delay(this.thirdMethod);
console.log('This is the constructor');
}
firstMethod(val) {
console.log('This is the First Method', val);
}
secondMethod(val) {
console.log('This is the Second Method', val);
}
thirdMethod(val) {
console.log('This is the Third Method', val);
}
}
new TimePopup()
.firstMethod(1)
.secondMethod(2)
.thirdMethod(3);
您遇到的问题是 delay
没有安排事情 运行 相对于彼此 。每件事都在它被调用的时间准确延迟,因此 new TimePopup().firstMethod(1).secondMethod(2).thirdMethod(3);
将同时调用所有三个方法,并且每个方法相对于调用时间延迟相同的时间量。然后两秒后三个都开火。
相反,您需要按顺序处理它们。类似于 ,您可以使用创建一个承诺队列来处理序列。每个方法 添加到链 而不是在执行之前有一个延迟:
const wait = ms => () =>
new Promise(resolve => setTimeout(resolve, ms));
let queue = Promise.resolve();
function delay(func) {
return function(...args) {
queue = queue
.then(wait(2000))
.then(() => func.apply(this, [...args]));
return this;
};
}
class TimePopup {
constructor() {
this.firstMethod = delay(this.firstMethod);
this.secondMethod = delay(this.secondMethod);
this.thirdMethod = delay(this.thirdMethod);
console.log('This is the constructor');
}
firstMethod(val) {
console.log('This is the First Method', val);
}
secondMethod(val) {
console.log('This is the Second Method', val);
}
thirdMethod(val) {
console.log('This is the Third Method', val);
}
}
new TimePopup()
.firstMethod(1)
.secondMethod(2)
.thirdMethod(3);
一种更可重用的方法是按需创建 delay
函数,这样您就可以为不同的任务设置不同的队列。这看起来像这样:
const delayMaker = delayBetween => {
let queue = Promise.resolve();
return function delay(func) {
return function(...args) {
queue = queue
.then(wait(delayBetween))
.then(() => func.apply(this, [...args]));
return this;
};
}
}
/* ... */
const delay = delayMaker(2000);
const wait = ms => () =>
new Promise(resolve => setTimeout(resolve, ms));
const delayMaker = delayBetween => {
let queue = Promise.resolve();
return function delay(func) {
return function(...args) {
queue = queue
.then(wait(delayBetween))
.then(() => func.apply(this, [...args]));
return this;
};
}
}
class TimePopup {
constructor() {
const delay = delayMaker(2000);
this.firstMethod = delay(this.firstMethod);
this.secondMethod = delay(this.secondMethod);
this.thirdMethod = delay(this.thirdMethod);
console.log('This is the constructor');
}
firstMethod(val) {
console.log('This is the First Method', val);
}
secondMethod(val) {
console.log('This is the Second Method', val);
}
thirdMethod(val) {
console.log('This is the Third Method', val);
}
}
new TimePopup()
.firstMethod(1)
.secondMethod(2)
.thirdMethod(3);
在 pre-promise 时代,一种流行的方法是传递一个 next
函数,该函数应该将下一个排队的任务从堆栈中移出并 运行 它。一个简化的例子:
class App {
funcs = [];
use(func) {
this.funcs.push(func)
return this
}
next() {
if (this.funcs.length)
this.funcs.shift()(this.next.bind(this))
}
}
//
function delay(func) {
return function (next) {
setTimeout(() => {
func();
next();
}, 1000);
}
}
//
(new App())
.use(delay(() => console.log(1)))
.use(delay(() => console.log(2)))
.use(delay(() => console.log(3)))
.next()
为什么链中的所有方法同时执行?我将方法包装在 setTimeout 中。我做错了什么?
我知道如何使用 promise 来做到这一点,但我正在学习链接技术。
const delay = function delay(func) {
return function(...args) {
setTimeout(() => {
return func.apply(this, [...args]);
}, 2000);
return this;
};
}
class TimePopup {
constructor() {
this.firstMethod = delay(this.firstMethod);
this.secondMethod = delay(this.secondMethod);
this.thirdMethod = delay(this.thirdMethod);
console.log('This is the constructor');
}
firstMethod(val) {
console.log('This is the First Method', val);
}
secondMethod(val) {
console.log('This is the Second Method', val);
}
thirdMethod(val) {
console.log('This is the Third Method', val);
}
}
new TimePopup()
.firstMethod(1)
.secondMethod(2)
.thirdMethod(3);
您遇到的问题是 delay
没有安排事情 运行 相对于彼此 。每件事都在它被调用的时间准确延迟,因此 new TimePopup().firstMethod(1).secondMethod(2).thirdMethod(3);
将同时调用所有三个方法,并且每个方法相对于调用时间延迟相同的时间量。然后两秒后三个都开火。
相反,您需要按顺序处理它们。类似于
const wait = ms => () =>
new Promise(resolve => setTimeout(resolve, ms));
let queue = Promise.resolve();
function delay(func) {
return function(...args) {
queue = queue
.then(wait(2000))
.then(() => func.apply(this, [...args]));
return this;
};
}
class TimePopup {
constructor() {
this.firstMethod = delay(this.firstMethod);
this.secondMethod = delay(this.secondMethod);
this.thirdMethod = delay(this.thirdMethod);
console.log('This is the constructor');
}
firstMethod(val) {
console.log('This is the First Method', val);
}
secondMethod(val) {
console.log('This is the Second Method', val);
}
thirdMethod(val) {
console.log('This is the Third Method', val);
}
}
new TimePopup()
.firstMethod(1)
.secondMethod(2)
.thirdMethod(3);
一种更可重用的方法是按需创建 delay
函数,这样您就可以为不同的任务设置不同的队列。这看起来像这样:
const delayMaker = delayBetween => {
let queue = Promise.resolve();
return function delay(func) {
return function(...args) {
queue = queue
.then(wait(delayBetween))
.then(() => func.apply(this, [...args]));
return this;
};
}
}
/* ... */
const delay = delayMaker(2000);
const wait = ms => () =>
new Promise(resolve => setTimeout(resolve, ms));
const delayMaker = delayBetween => {
let queue = Promise.resolve();
return function delay(func) {
return function(...args) {
queue = queue
.then(wait(delayBetween))
.then(() => func.apply(this, [...args]));
return this;
};
}
}
class TimePopup {
constructor() {
const delay = delayMaker(2000);
this.firstMethod = delay(this.firstMethod);
this.secondMethod = delay(this.secondMethod);
this.thirdMethod = delay(this.thirdMethod);
console.log('This is the constructor');
}
firstMethod(val) {
console.log('This is the First Method', val);
}
secondMethod(val) {
console.log('This is the Second Method', val);
}
thirdMethod(val) {
console.log('This is the Third Method', val);
}
}
new TimePopup()
.firstMethod(1)
.secondMethod(2)
.thirdMethod(3);
在 pre-promise 时代,一种流行的方法是传递一个 next
函数,该函数应该将下一个排队的任务从堆栈中移出并 运行 它。一个简化的例子:
class App {
funcs = [];
use(func) {
this.funcs.push(func)
return this
}
next() {
if (this.funcs.length)
this.funcs.shift()(this.next.bind(this))
}
}
//
function delay(func) {
return function (next) {
setTimeout(() => {
func();
next();
}, 1000);
}
}
//
(new App())
.use(delay(() => console.log(1)))
.use(delay(() => console.log(2)))
.use(delay(() => console.log(3)))
.next()