求助,关于Promise,谢谢大佬。
发布于 6 年前 作者 sevenzhou1218 2570 次浏览 来自 问答

有一个需求,比方说是一个任务队列[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 厉害! 我会尝试着用你这个思路去改写我的代码的,谢谢。

回到顶部