Rain120 / Web-Study

日常学习,工作写的笔记
66 stars 108 forks source link

实现一个 runAllTask #25

Open Rain120 opened 2 years ago

Rain120 commented 2 years ago

题目

const input = [{
    id: 'task1',
    deps: [],
    runTask: () => 3,
}, {
    id: 'task2',
    deps: ['task1', 'task3'],
    // res1 task1的 runTask(), res3 task3的runTask()
    runTask: (res1, res3) => 1 + res1 + res3,
}, {
    id: 'task3',
    deps: ['task1'],
    runTask: (res1) => 5 + res1,
}, {
    id: 'task4',
    deps: ['task1', 'task2'],
    runTask: (res1, res2) => 3 + res1 + res2,
}, ];

runAllTask(input, (err, res) => {
    console.log(res);
    /** 
        res应该为:
        { task1: 3, task2: 12, task3: 8, task4: 18 }
    */
});
Rain120 commented 2 years ago
function runAllTask(list, cb) {
    const map = new Map();

    try {
        while (list.length) {
            const cur = list.shift();

            if (!cur.deps.length) {
                map.set(cur.id, cur.runTask());
            } else {
                const params = [];

                const finished = cur.deps.every(dep => {
                    if (map.has(dep)) {
                        params.push(map.get(dep));
                        return true;
                    } else {
                        list.push(cur);
                        return false;
                    }
                });

                if (finished) {
                    const res = cur.runTask(...params);
                    map.set(cur.id, res);
                }
            }
        }

        cb(null, Object.fromEntries(map));
    } catch (error) {
        cb(error, null);
    }
}
Rain120 commented 2 years ago
function runAllTask(list, cb) {
    const map= {};
    const res = {};

    function runOneTask(id, deps = []) {
        if (res[id]) {
            return res[id];
        }

        const depRes = [];
        map[id].deps.forEach(dep => {
            deps.push(dep);
            depRes.push(runOneTask(dep, deps))
        });

        res[id] = map[id].runTask(...depRes);
        deps = deps.filter(item => item === id);

        return res[id];
    }

    try {
        list.forEach(item => {
            map[item.id] = item;
        });

        list.forEach(item => {
            runOneTask(item.id);
        });

        cb(null, res);
    } catch (error) {
        cb(error, null);
    }
}