1. 程式人生 > >ES6由一道前端阿里面試題的思考

ES6由一道前端阿里面試題的思考

題目

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的設定的tiemout比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.jianshu.com/p/e4965b6af6b3 來源:簡書 簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。