实现一个arrange函数,可以进行时间和工作调度

发布于 2022-09-12 13:02:33 字数 506 浏览 33 评论 0

实现一个arrange函数,可以进行时间和工作调度

//  [  >  …  ]  表示调用函数后的打印内容

//  arrange('William');
//  >  William  is  notified

//  arrange('William').wait(5).do('commit');
//  >  William  is  notified
//  等待  5  秒
//  >  Start  to  commit

//  arrange('William').waitFirst(5).do('push');
//  等待  5  秒
//  >  Start  to  push
//  >  William  is  notified

这不是一个简单的问题。
一道面试题,网上没找到答案;我试了很久没做对;
初步判断需要实现一个任务队列;
然后通过一些方式让一些任务立即执行,延后执行

我很想通过这个demo 学会调度方面的知识;再次感谢

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一世旳自豪 2022-09-19 13:02:33

和下面这个问题几乎一摸一样

https://segmentfault.com/q/10...

另外我司也用类似的问题作为面试题

像极了他 2022-09-19 13:02:33

尝试写了一下,用了Proxy以及用了两个数组做了简单的优先级,结果和期望一致:

const arrange = name => {
    const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

    const list = [];
    const priorityList = [];
    let _priority = false;
    list.push(() => console.log(`${name} is notified`));

    const chain = new Proxy({}, {
        get(_, prop) {
            return data => {
                const [_, method, priority = _priority] = /^(\w+?)(First)?$/[Symbol.match](prop);
                _priority = priority;
                if (method === 'wait') {
                    (priority ? priorityList : list).push(async () => await wait(data * 1000));
                } else if(method === 'do') {
                    (priority ? priorityList : list).push(() => console.log(`Start to ${data}`));
                }
                return chain;
            }
        }
    });

    setTimeout(async () => {
        for (let func of priorityList) {
            await func();
        }

        for (let func of list) {
            await func();
        }
    }, 0)

    return chain;
};

// arrange('William');
// arrange('William').wait(5).do('commit');
arrange('William').waitFirst(5).do('push');
不醒的梦 2022-09-19 13:02:33

image.png

class Arrange {
    index = 0
    promises: Array<string | Promise<any>> = []
    constructor(info: string) {
        this.promises = [`${info} is notified`]
        this.index++
    }
    // 出现 `waitFirst` 从前面载入
    waitFirst = (s: number) => {
        this.promises.unshift(new Promise(resolve => setTimeout(resolve, s * 1000)))
        this.index = 1
        return this
    }
    // 出现 `wait` 消除 `waitFirst` 效果
    wait = (s: number) => {
        this.promises.splice(this.index, 0, new Promise(resolve => setTimeout(resolve, s * 1000)))
        this.index = this.promises.length
        return this
    }
    do = (task: 'commit' | 'push') => {
        switch (task) {
            case 'commit': this.promises.splice(this.index, 0, `Start  to  commit`); break;
            case 'push': this.promises.splice(this.index, 0, 'Start  to  push'); break;
            default: break;
        }
        this.index++
        return this
    }
    run = async (log = (info: any) => {}) => {
        for (let i = 0; i < this.promises.length; i++) {
            const info = await Promise.resolve(this.promises[i]);
            log && info && log(info)
        }
        return this
    }
}

const arrange = (s = '') => {
    const a = new Arrange(s)
    setTimeout(() => {
        console.time('run:')
        a.run(function (info) {
            console.timeLog('run:', info)
        })
    }, 0);
    return a
}

// arrange('William');
// arrange('William').wait(5).do('commit');
arrange('William').waitFirst(5).do('push');
风为裳 2022-09-19 13:02:33
function arrange(str){
    var org_value=str;
    var action_type ='';
    var push_action = function(){
        return 'Start to '+action_type;
    };
    var commit_action = function(){
        return 'Start to '+action_type;
    };

    var default_action = function(){
        var result = org_value+'  is not notified';
        console.log(result);
        return result;
    };

    var do_spect_action = function(){
        var result = '';
        switch(action_type){
            case 'push':{
                result = push_action();
                break;
            }
            case 'commit':{
                result = commit_action();
                break;
            }
            default:{
                result = default_action();
                break;
            }
        };
        console.log(result);
        return result;
    };

    var _wait_ = function(waitTime){
        var that =this;
        default_action();
        if(action_type){
            setTimeout(function(){
                console.log('等待' + waitTime+'秒后 ');
                do_spect_action();
            },waitTime*1000);
        }
      return that;
    };
    
    var _waitFirst_ = function(waitTime){
      var that =this;
      if(action_type){
        setTimeout(function(){
          console.log('等待' + waitTime+'秒后 ');
          do_spect_action();
          default_action();
        },waitTime*1000);
      }
      return that;
    };
    
    var _real_action_ = do_spect_action;
        
    return {
        wait:function(waitTime){
            _real_action_ = _wait_.bind(this,waitTime);
            return this;
        },
    
        waitFirst:function(waitTime){
            _real_action_ = _waitFirst_.bind(this,waitTime);
            return this;
        },
        do:function(actionType){
          action_type = actionType;
          _real_action_();
          return this;
        },
            
        valueOf:function(){
            return default_action();
        },
        toString:function(){
            return default_action();
        }
    }
}

arrange('William').wait(5).do('commit');
arrange('William').waitFirst(5).do('push');
游魂 2022-09-19 13:02:33
arrange('William');

按你说的调用后是立即输出,不可能实现。基本上都是在下一个事件循环, 根据参数构建好队列执行

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文