求助,关于Promise,谢谢大佬。
有一个需求,比方说是一个任务队列[taskA, taskB,taskC,taskD,…],他们按照顺序执行(先吃饭,吃饭完成后,再去喝水,喝完以后再去上班,等等),然后我需要给他们提供一个暂停的功能,我的想法是给他们提供一个无限暂停的方法,于是就想到了下面的两个方法。好像废话有点多,不知道有没有表达清楚。
问题1:doWait1这个写法可行吗? 理论上一个Promise如果没有resolve或者reject,那么他的状态会一直是pending,那么他是不是应该能起到无限暂停的功能,等待收到继续指令时,执行g.resolve(true);? 问题2: 如果doWait1这种写法可行,那么和doWait2方法相比哪个方法好?doWait2的想法是,提供一个递归吧,让他一直setTimeout,直到收到继续指令,将flag的值变为false时停止。
求大神指导,谢谢。
const g = {};
let flag = true;
function doWait1(){
return new Promise((resolve, reject)=>{
g.resolve = resolve;
g.reject = reject;
//注意:没有任何其他代码,更没有resolve或者reject
});
}
function doWait2(data){
return new Promise((resolve, reject)=>{
//timer取多少合适?
setTimeout(()=>{
resolve(data);
}, 100);
}).then((d)=>{
if(d){
//继续等待
console.info('waiting');
return doWait2(flag);
}else{
//等待结束
console.info('finished');
return true;
}
});
}
4 回复
感觉dowait1好一些
不过用async/await的话会更简单解决这个问题
胡乱写了一个
function sleep(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
function createTask(name, time) {
return async() => {
console.log(`task${name} start`);
await sleep(time);
console.log(`task${name} resolved`);
}
}
class PauseableTaskQueue {
constructor(tasks) {
this.queue = tasks;
this.status = 'run';
this.running = false;
this.start();
}
async start() {
this.running = true;
while (this.status === 'run' && this.queue.length) {
await this.queue.shift()();
}
this.running = false;
}
run() {
this.status = 'run';
if (!this.running) this.start();
}
pause() {
this.status = 'pause';
}
}
const q = new PauseableTaskQueue([
createTask('A', 5000),
createTask('B', 6000),
createTask('C', 7000),
]);
// q.pause();
// q.run();
下面代码引用自 Deferred
function Deferred() {
// update 062115 for typeof
if (typeof(Promise) != 'undefined' && Promise.defer) {
//need import of Promise.jsm for example: Cu.import('resource:/gree/modules/Promise.jsm');
return Promise.defer();
} else if (typeof(PromiseUtils) != 'undefined' && PromiseUtils.defer) {
//need import of PromiseUtils.jsm for example: Cu.import('resource:/gree/modules/PromiseUtils.jsm');
return PromiseUtils.defer();
} else {
/* A method to resolve the associated Promise with the value passed.
* If the promise is already settled it does nothing.
*
* @param {anything} value : This value is used to resolve the promise
* If the value is a Promise then the associated promise assumes the state
* of Promise passed as value.
*/
this.resolve = null;
/* A method to reject the assocaited Promise with the value passed.
* If the promise is already settled it does nothing.
*
* @param {anything} reason: The reason for the rejection of the Promise.
* Generally its an Error object. If however a Promise is passed, then the Promise
* itself will be the reason for rejection no matter the state of the Promise.
*/
this.reject = null;
/* A newly created Promise object.
* Initially in pending state.
*/
this.promise = new Promise(function(resolve, reject) {
this.resolve = resolve;
this.reject = reject;
}.bind(this));
Object.freeze(this);
}
}
@William17 嘿,谢谢,这段代码至少让我知道,我的第一个写法是没问题的。
@dislido 厉害! 我会尝试着用你这个思路去改写我的代码的,谢谢。