如何用Promise实现一个任务队列

工作中遇到一个业务需求。
实行一个任务队列,前一个任务执行完了以后再去执行下一个任务。我本想用promise实行一个异步串行的队列。但这次情况跟以往不一样。想了有一段时间想不出来了,求教大佬~

业务场景抽象出来是:
存在如下任务队列 T = [A,B]
同时全局下面已经存在有一个监听函数 F = onStateChange(res => 'res是我想要判断的值')
A和B都安上一个run方法(返回promise),该方法会执行一段触发State改变的逻辑,然后再根据res的值决定是resolve还是reject

具象出来是:
小程序连接蓝牙 需要给蓝牙设备发送好几条指令 根据上一条指令是否通过才能进行下一条指令。

阅读 4.7k
2 个回答

按你的意思是每个任务的状态全是会变成完成的是吗?
假设你的监听函数监听的是State这个变量,那么在每个任务结束是判断下这个变量的值来决定是否退出。

async function t(){
    const T=[A,B];
    for(let i=0;i<T.length;i++){
        await T[i].run();
        // 假设失败会改成`failed`
        if(State=="failed"){
            console.log("队列任务失败");
            break;
        }
    }
}

根据你的描述,大概模拟了一下、你看是否使用你的场景、最近正好也写过类似的场景、改了一下

// 任务列表

var T = [];
//全局监听执行方法
function onStateChange(){
    //随机成功失败
    return Promise.resolve(Math.random() > 0.5) ;
}
// 任务队列生成方法,生成10个
function taskFactory(){
    for(var i=0;i<10;i++){
        T.push(
            {
                name: i,
                run: function(){
                    var self = this;
                    return new Promise(function(resolve,reject){
                        
                        //触发onStateChange ,根据结果决定是否继续执行
                        onStateChange().then( function(isResolve){
                            if(isResolve){
                                console.log('成功执行任务' + self.name);
                                resolve('成功执行任务' + self.name);
                            }else{
                                console.log('执行任务失败,终止任务' + self.name);
                                reject('执行任务失败,终止任务' + self.name);
                            }
                        })
                    })
                }
            }
        )
    }
}

// 生成任务队列内容
taskFactory();

//队列序号
var index = 0;

//执行任务队列方法
function doTask(){
    if(index == T.length-1){
        return Promise.resolve('任务列表执行完毕');
    }
    return new Promise(function(resolve,reject){
        T[index].run().then(function(result){
            index ++;
            resolve(doTask());
        }).catch(function(failresult){
            resolve(failresult);
        });
    });
}

// 执行任务队列
doTask().then(function(result){
    console.log("result:" + result);
});

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题