用Promise控制異步流程,三個異步任務,時間可能有先後,但是要按照想要的順序輸出。
我這裏用四種方法解決,其實也就是考察你對Promise的理解,基礎題了。
//實現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接受即可。
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.最暴力的直接手寫鏈
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的殼。
到此結束,各位有啥意見可以留個言。