美文网首页Javascript收集
由一道前端阿里面试题的思考

由一道前端阿里面试题的思考

作者: 扶搏森 | 来源:发表于2018-08-06 01:57 被阅读13次

    题目

    const timeout = ms =>
        new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve();
            }, ms);
        });
    
    const ajax1 = () =>
        timeout(2000).then(() => {
            console.log("1");
            return 1;
        });
    
    const ajax2 = () =>
        timeout(1000).then(() => {
            console.log("2");
            return 2;
        });
    
    const ajax3 = () =>
        timeout(2000).then(() => {
            console.log("3");
            return 3;
        });
    
    // 在mergePromise编写代码,使得执行结果为: 1  2  3 done [1,2,3]
    const mergePromise = (ajaxArray) => {
        // 此处写代码
        
    }
    mergePromise([ajax1, ajax2, ajax3])
        .then(data => {
            console.log("done");
            console.log(data); // data 为 [1, 2, 3]
        });
    
    // 执行结果为: 1  2  3 done [1,2,3]
    

    注意其中的ajax1的设置的timeout比ajax2的长,所以同步执行的话,先输出2。

    调用mergePromise后可执行then,所以mergePromise 返回Promise对象或者async函数本身也是Promise

    利用await 将异步变同步

    const mergePromise = async (ajaxArray) => {
        let arr = []
        for(let ajax of ajaxArray) {
            arr.push(await ajax())
        }
        return arr
    }
    

    promise和await 结合,其实和第一种没太大区别

    const mergePromise = async (ajaxArray) => {
        return new Promise(async (resolve, reject) => {
            let arr = [];
            for(let ajax of ajaxArray) {
                arr.push(await ajax())
            }
            resolve(arr)
        })}
    

    我试过 Promise.all方法,但是 输出的是 2 1 3 done [1,2,3],如果有哪个大神找到只用Promise的方法,请在评论区留言,谢谢。

    问题提问者想出的方法

    promise和reduce

    const mergePromise = (ajaxArray) =>{
        //1,2,3 done [1,2,3]
        return ajaxArray.reduce((preajax, ajax)=>{
            return new Promise((resolve)=>{
                if(typeof preajax === "function") preajax = preajax();
                preajax.then(predata=>{
                    ajax().then(data=>{
                        resolve([].concat(predata).concat(data));
                    })
                });
            });
        })
    }
    

    很敬佩的一位前端老师的方法,暂时没理解他的写法。需要慢慢研究一下

    1. 不对现有代码引入任何的新语法
    2. 用到了遍历器的数据结构
    3. 用到了尾递归
    4. 巧妙的用了你的timeout我用了0构建了 macrotask
    5. 用了函数式编程最经典的直接挂方法 避开了then
    const mergePromise = (ajaxArray) => {
        //1,2,3 done [1,2,3]
        var arr = [],
            ajaxLength = ajaxArray.length;
        for (var i = 0; i < ajaxLength; i++) {
            ajaxArray[i].next = ajaxArray[i + 1];
        }
    
        function todo(item) {
            item().then(data => {
                arr.push(data);
                var _next = item.next;
                _next && todo(_next);
            });
        }
        todo.then = (data) => {
            ajaxArray[ajaxLength - 1].next = () =>
                timeout(0).then(() => {
                    data(arr)
                });
            todo(ajaxArray[0]);
        }
        return todo;
    }
    
    

    题目肯定都很难,要多想想,不能一开始就放弃,遇到难的东西太多了,只能靠自己去解决。不能给自己想后路,不懂还有其他大神抗着。

    相关文章

      网友评论

        本文标题:由一道前端阿里面试题的思考

        本文链接:https://www.haomeiwen.com/subject/isaivftx.html