首页 > 解决方案 > Javascript - 如何使用 javascript 回调进行阻塞

问题描述

这是我坚持的问题的简化版本。我希望能够创建一个调度程序类,以便它具有一个函数 addTask(),它将任务函数作为参数。该类还有一个开始函数 runSchedule(),它可以同步或按顺序运行任意数量的添加任务。我认为也许我可以用一系列 Promises 来做这样的事情,但我之前没有使用过 Promises,但是研究和尝试使用它并没有给我带来任何有用的东西。

有没有办法将函数参数存储到 addTask(),然后在调用 runSchedule() 期间按顺序调用所有添加的任务?如果任务成功运行,则调用成功回调。如果一项任务失败,则停止并且不再执行任何任务,并调用错误回调。

class Schedule {
    constructor( ) {
        this.tasks = []
    }

    addTask( task ) {
        this.tasks.push( task )
        // added to list of promises here
        // currently just adding function to an array
    }

    runSchedule( success, error ) {
        try {
            // run the tasks here
            success()
        } catch (e) {
            error()
        }
    }
}

s = new Schedule()

// first
s.addTask( function(goToNext, stopRunning) {
    this.value1 = true
    goToNext();
});

// second
s.addTask( function(goToNext, stopRunning) {
    if (!this.value1) {
        stopRunning();
    }
    var self = this
    setTimeout(function() {
        self.value2 = true
        goToNext();
    }, 1000);
});

// run first task, then second task
s.runSchedule(function () {
    console.log(this.value1)
    console.log(this.value2)
}, function (error) {
    console.log("error: " + error)
}

标签: javascriptnode.js

解决方案


class Schedule {
    constructor( ) {
        this.tasks = []
    }

    addTask( task ) {
        this.tasks.push( task )
        // added to list of promises here
        // currently just adding function to an array
    }

    runSchedule( success, error ) {
        try {
            run(this.tasks.pop());// use tasks.shift() if you want to go from begining 

        } catch (e) {
            error()
        }
    }

    run(task){
        task()
        .then(()=>{
            if(this.tasks>0){
                run(this.tasks.pop())
            }
            else{
                success()
            }
        })
        .catch(()=>{
            //call your failure here 
        })
    }
}

应该像这样添加任务

s.addTask(function(){
    return new Promise((success, failure)=>{
        //do your work at the end call success() or failure()
    });
});

添加了一个新方法run,它接受一个task作为参数并在执行成功时执行,然后递归调用run,直到所有任务都完成,如果所有任务都完成而不是调用success(),如果有错误则处理你的失败

我们必须更改任务,每个任务都返回承诺,如果成功,则在承诺中执行您的工作调用success()else 。failure()

注意:无法测试这个,写形式电话,请寻找错字


推荐阅读