头几天碰到一个编程题,请求掌握promise递次实行,本日总结了一下这个至少有好四种要领都可以完成,包含promise嵌套,经由过程一个promise串起来,generator,async完成,以下一一引见。
原问题以下:
//完成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]
一. promise嵌套
function mergePromise1(ajaxArray) {
let arr = [];
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;
});
}
二. Promise.resolve将promise串连成一个使命行列
function mergePromise2(ajaxArray) {
let p = Promise.resolve();
let arr = [];
ajaxArray.forEach(promise => {
p = p.then(promise).then((data) => {
arr.push(data);
return arr;
});
});
return p;
}
此要领相对于上面的要领简朴而且誊写直观易懂,另有一品种似的使命行列,将数组按递次从左侧头部掏出一个实行,实行完成后触发自定义next要领,next要领担任从数组中掏出下一个使命实行。
三. generator函数
1. 原生generator函数
var mergePromise3 = function* (ajaxArray) {
let p1 = yield ajaxArray[0]();
let p2 = yield ajaxArray[1]();
let p3 = yield ajaxArray[2]();
return Promise.resolve([p1,p2,p3]);
}
//自动运转的run
function run(fn) {
return new Promise((resolve, reject) => {
var g = fn;
let arr = [];
function next(preData) {
if(preData) { //如果有数据则push进数组
arr.push(preData);
}
let result = g.next(preData); //猎取每一步实行效果,个中value为promise对象,done示意是不是实行完成
if (result.done) { //函数实行终了则resolve数组
resolve(arr);
}
else { //函数没有实行终了则递归实行
result.value.then(function(nowData) {
next(nowData);
});
}
}
next();
});
}
运用这类要领须要修正mergePromise要领为:
run(mergePromise3([ajax1, ajax2, ajax3])).then(data => {
console.log('done');
console.log(data); // data 为 [1, 2, 3]
});
2. 应用co模块自动实行
const co = require('co')
co(mergePromise3([ajax1, ajax2, ajax3])).then(data => {
console.log('done');
console.log(data); // data 为 [1, 2, 3]
});
此要领道理和上面一样,只是运用已有的封装好的co模块来自动实行
四. async函数
function mergePromise4(ajaxArray) {
let arr = [];
async function run() {
for(let p of ajaxArray) {
let val = await p();
arr.push(val);
}
return arr;
}
return run();
}
以上列出了四种要领,详细运用那种要领也依据喜欢而定,如果有其他的好的要领迎接留言补充。