美文网首页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