promise
// 比较传统的回调方式与promise
// 回调方法 用于请求数据(模拟)
function f(cb) {
setTimeout(function() {
cb && cb();
}, 1000);
}
f(function() {
console.log(1);
f(function() {
console.log(2);
f(function() {
console.log(3);
f(function() {
console.log(4);
f(function() {
console.log(5);
f(function() {
console.log(6);
});
});
});
});
});
});
// promise方法 用于请求数据(模拟)
function f() {
return new Promise(resolve => {
setTimeout(function() {
resolve();
}, 1000);
})
}
f()
.then(function() {
console.log(1);
return f();
})
.then(function() {
console.log(2);
return f();
})
.then(function() {
console.log(3);
});
对比回调与promise的流程控制:
一个动画函数
//使用回调函数实现
function moveTo(el, x, y, cb) {
el.style.transform = `translate(${x}px, ${y}px)`;
setTimeout(function() {
cb && cb();
}, 1000);
}
let el = document.querySelector('div');
document.querySelector('button').addEventListener('click', e => {
moveTo(el, 100, 100, function() {
moveTo(el, 200, 200, function() {
moveTo(el, 30, 20, function() {
moveTo(el, 100, 300, function() {
moveTo(el, 130,20, function() {
moveTo(el, 0, 0, function() {
console.log('移动结束!');
});
});
});
});
});
});
});
实例化Promise构造函数时,传递一个函数,该函数有两个参数:resolve和reject(也是两个函数,名字可以随便取,就是两个函数,第一个函数是用来处理成功时的回调函数,第二个函数是用来处理失败时的回调函数)
实例化后的Promise对象,具有then方法,then方法用来指定上述两个函数,resolve和reject;
then方法中也可以直接在后面继续调用then方法,如果then方法返回一个Promise的实例,那下一个then就会以上一个返回的Promise的实例去执行;若没有返回promise实例,则会继续执行,相当于将下面then方法中的代码写入未返回promise实例的then方法中。
then()方法接收两个参数:
1.第一个参数是状态切换为成功时的回调,
2.第二个参数是状态切换为失败时的回调。如果在then中不添加参数,那么就相当于没有调用任何回调函数
//使用promise实现
function moveTo(el, x, y) {
return new Promise(resolve => {
el.style.transform = `translate(${x}px, ${y}px)`;
setTimeout(function() {
resolve();
}, 1000);
});
}
let el = document.querySelector('div');
document.querySelector('button').addEventListener('click', e => {
moveTo(el, 100, 100)
.then(function() {
console.log('第一次移动');
return moveTo(el, 200, 200);
})
.then(function() {
console.log('第二次移动');
})
.then(function() {
console.log('第二次移动');
});
});
使用promise的链式结构做流程控制,更利于维护、可读性更强。