0

我有一个类,它管理一个函数队列并提供一个简单的 API manager.queue({data: foo}, function, callback),然后在我的渲染器进程中单击一个按钮,我调用它来对各种预定义函数进行排队,但这里的问题是最后一个函数可以使用来自第一个功能。

我最初尝试的是:
起初我将返回数据存储在results: any[] = []回调中的一个变量中,然后当我想将第二个任务排队时,我会简单地manager.queue({data: results[0], function2, callback);.

现在,显然这不起作用,因为 JavaScript 是按值传递的,并且result[0]是在队列时传递的,而不是在函数执行时从数组中读取值

当前实现:
目前我延迟排队,直到排队功能完成。即我创建了一组任务,它们调用manager.queue....而不是直接排队,然后在我的回调函数中tasks.shift()() //which adds a the function to queueawait manager.start()因为管理器的队列中总是只有一个项目,所以它停止,执行回调,然后将另一个函数添加到队列并重新启动管理器使函数出队。

问题:这工作正常,但它破坏了管理器类的观点,调用类不应该跟踪任务和结果,而只需将任务排队并让管理器使用第二个成功的结果功能。

现在理论足够了,是时候写一些代码了:)

Manager.ts  

interface TaskFunctionArguments<JobData>
{
    data: JobData
};

export type TaskFunction<JobData, ReturnData> = (
    arg: TaskFunctionArguments<JobData>
) => Promise<ReturnData>;

export default class Manager<JobData = any, ReturnData = any>
{
    private jobQueue: Queue<Job<JobData, ReturnData>> = new Queue<Job<JobData, ReturnData>>();

    public queue(data: JobData, task: TaskFunction<JobData, ReturnData>, callbacks?: ExecuteCallbacks)
    {
        const job = new Job<JobData, ReturnData>(data, task, callbacks);
        this.jobQueue.push(job);
    }

    public async start()
    {
        let job;
        let result: any;
        let errorState: Error | null = null;
        while (this.jobQueue.size())
        {
            job = this.jobQueue.shift();
            try
            {
                result = await job.taskFunction({ data: job.data as JobData });
            }
            catch (err)
            {
                errorState = err;
            }

            if (errorState)
            {
                job.executeCallbacks.reject(errorState || new Error("asf"));
                return { type: "error", error: errorState || new Error("asf") };
            }
            else
            {
                job.executeCallbacks.resolve(result);
                // return { type: "success", data: result };
            }
        }
        return { type: "success", data: result };
    }
}

代码是从中获得灵感/复制的,puppeteer-cluster因为如果我编写了相同的代码,那将是一团糟:P,我想在打字稿中学习泛型。

当前实现调用者代码

var tasks: ((value?: any) => void)[] = [];
var results: any[] = [];

//callback code
async (r) => 
{
    results.push(r);
    if (tasks.length)
    {
       tasks.shift()();
       let result = await manager.start();
       console.log("result: ", result);
    }
}

//when I click want to add a function
tasks.push(() => 
{
   manager.queue({data:foo}, function, callback);
};

//to queue the second task
tasks.push(() =>
{
   //mostly result[0] is parsed like: result[0] as MyInterface
   manager.queue({data: results[0]}, function2, callback});
};

//When I want to start the queue
tasks.shift()();
await manager.start();
4

0 回答 0