一道promise的小題目(Promise異步流程控制)

用Promise控制異步流程,三個異步任務,時間可能有前後,可是要按照想要的順序輸出。
我這裏用四種方法解決,其實也就是考察你對Promise的理解,基礎題了。ajax

//實現mergePromise函數,把傳進去的數組順序前後執行,
//而且把返回的數據前後放到數組data中

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;
});



function mergePromise(ajaxArray) {
//todo 補全函數
}

mergePromise([ajax1, ajax2, ajax3]).then(data => {
    console.log('done');
    console.log(data); // data 爲 [1, 2, 3]
});

// 分別輸出
// 1
// 2
// 3
// done
// [1, 2, 3]

也就是補全上面的mergePromise函數,獲得如上的輸出。數組

1.最好的方案async

function mergePromise(ajaxArray) {
    let arr = [];
    async function run() {
        for(let ifun of ajaxArray) {
            let cur = await ifun();
            arr.push(cur);
        }
        return arr;
    }
    return run();
}

2.本身構造then的鏈

function mergePromise(ajaxArray){
    let arr = [];
    let p = Promise.resolve();
    ajaxArray.forEach(item=>{
        p = p.then(data=>{
            console.log(data);
            if(data){
                arr.push(data);
            }
            return item();
        });
    })
    return p.then(data=>{
        arr.push(data);
        return arr;
    })
}

先加一層完成狀態的promise(即Promise.resolve()),而後構造一層then鏈,注意第一層是沒有data的,第一次返回的是item(),也就是ajax1(),返回了1,下一步纔有data,即data是1,最後一個item()就是ajax3(),調用並return,咱們要額外在外面用then接受上一步狀態改變的結果也就是上一步return的3(promise中直接return的話是返回resolve的狀態)最後返回arr,讓mergerPromise接受便可。promise

3.遞歸,另外一種思路

let timeout = function (num, ms) {
    return new Promise(function (resolve,reject) {
        setTimeout(() => {
            resolve(num);
        }, ms)
    });
}

let timeout1 = timeout(1, 500);
let timeout2 = timeout(2, 2000);
let timeout3 = timeout(3, 1000);

let myPromise = new Promise(function (resolve,reject) {
   
    let arr = [];
    let timeouts = [timeout1,timeout2,timeout3];
    runIndex(0);
    function runIndex(index){
        timeouts[index].then(data=>{
            console.log(data)
            arr.push(data);
            if(index<timeouts.length-1) {
                console.log('index',index);
                index++;
                runIndex(index);
            }else {
                resolve(arr);
            }
            
        })
    }
});


myPromise.then(data => {
    console.log(data);
    console.log("done!");
})

我以爲遞歸作這題就是一種bug的作法,徹底就是利用了遞歸的域環境的改變。異步

4.最暴力的直接手寫鏈async

function mergePromise(ajaxArray) {
    let arr = [];
    // ajaxArray[0]();
    return ajaxArray[0]().then(data=>{
        arr.push(data);
        return ajaxArray[1]();
    }).then(data=>{
        arr.push(data);
        return ajaxArray[2]();
    }).then(data=>{
        arr.push(data);
        return arr;
    })
}

也就是上個循環那個展開的樣子,好處就是不用加一層resolve的殼。函數


到此結束,各位有啥意見能夠留個言。code

相關文章
相關標籤/搜索