promise 异步编程的解决方案
这篇文章写的比较好 http://blog.csdn.net/u011500781/article/details/53055856
bluebird - 封装了 ES6 原生 Promise
jquery 1.5之后有了jQuery Deferred 是对promise规范的实现
复杂的AJAX嵌套可以改成如下形式
var promise1 = $.ajax(url1);
var promise2 = promise1.then(function(data){
return $.ajax(url2, { "data": data });
});
var promise3 = promise2.then(function(data){
return $.ajax(url3, { "data": data });
});
promise3.done(function(data){
// data retrieved from url3
});
如下是我自己的一点理解
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body {
background: black
}
img {
border-radius: 50%;
-webkit-animation: rotate 3s linear 0s infinite alternate;
-o-animation: rotate 3s linear 0s infinite alternate;
animation: rotate 3s linear 0s infinite alternate;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.eye {
width: 20px;
height: 20px;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 50%;
box-shadow: 30px 0px 0px 0px rgba(255, 255, 255, 0.8);
position: relative;
margin: 36px 26px;
}
.eye:after {
background-color: #59488b;
width: 10px;
height: 10px;
box-shadow: 30px 0px 0px 0px #59488b;
border-radius: 50%;
left: 9px;
top: 8px;
position: absolute;
content: "";
-webkit-animation: eyeball 2s linear infinite alternate;
-moz-animation: eyeball 2s linear infinite alternate;
animation: eyeball 2s linear infinite alternate;
}
@-webkit-keyframes eyeball {
0% {
left: 9px;
}
100% {
left: 1px;
}
}
@-moz-keyframes eyeball {
0% {
left: 9px;
}
100% {
left: 1px;
}
}
@keyframes eyeball {
0% {
left: 9px;
}
100% {
left: 1px;
}
}
</style>
</head>
<body>
<div class="eye"></div>
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524239827291&di=1ea316d9e0c45ed800220dfebdacb760&imgtype=0&src=http%3A%2F%2Fimg.lanqb.com%2F20160605%2F1465092344VOdLCUAW-f.jpg" width="200px" alt="">
<script>
// 一个promise代表一个异步操作的最终执行结果。让异步操作变得易于维护 职责单一
// 1模拟ajax 普通写法
{
//块级作用域
let ajax = function(callback) {
console.log('start 1');
setTimeout(function() {
callback && callback.call()
}, 1000)
}
ajax(function() {
console.log('get data success1')
})
}
// 2promise 方式
// 执行一个异步任务如下面的 ajax,会返回一个结果,这个结果是个promise ,它保证他将会变成一个成功或者失败
{
let ajax = function() {
console.log('start 2');
return new Promise(function(resolve, reject) {
//做一些异步操作
setTimeout(function() {
resolve()
}, 1000)
})
}
ajax().then(function() {
console.log('get data success2')
})
}
// 3串联操作
{
let ajax = function() {
console.log('start 3');
return new Promise(function(resolve, reject) {
//做一些异步操作
setTimeout(function() {
resolve()
}, 1000)
})
}
ajax()
.then(function() {
console.log('get data success2')
return new Promise(function(resolve, reject) {
//做一些异步操作
setTimeout(function() {
resolve()
}, 1000)
})
})
.then(function() {
console.log('get data success3')
})
}
// 4异常捕获. 可以捕获语法错误以及业务逻辑错误 Error和reject
{
let ajax = function(num) {
console.log('start 4');
return new Promise(function(resolve, reject) {
//做一些异步操作
//throw new Error('-----------wrong')
// setTimeout(function() {
if (num > 5) {
resolve()
} else {
reject('失败走这里')
}
// }, 1000)
})
}
ajax(6).then(function() {
console.log('get data success4')
}).catch(function(err) {
console.log('---catch', err)
})
ajax(3).then(function() {
console.log('get data success5')
}).catch(function(err) {
console.log('---catch', err)
})
}
//5 Promise.all 应用场景 所有图片加载完再添加到页面 优化用户体验
{
let loadImg = function(src) {
return promise = new Promise(function(resolve, reject) {
let img = document.createElement('img');
img.src = src;
img.onload = function() {
resolve(img) //异步成功执行resolve
}
img.onerror = function() {
reject(img) //异步失败执行reject
}
})
}
// 添加所有图片到页面
let addImagesToBody = function(imgs) {
imgs.forEach(function(img) {
document.body.appendChild(img)
})
}
//Promise.all 返回一个新的promise ,当数组中所有promise实例的状态发生改变之后 新的promise实例状态才发生变化
Promise.all([
loadImg('http://iconfont.alicdn.com/t/1494395652678.png@200h_200w.jpg'),
loadImg('http://iconfont.alicdn.com/t/1508911280546.jpg@200h_200w.jpg'),
loadImg('http://iconfont.alicdn.com/t/1493708103743.jpeg@200h_200w.jpg')
]).then(addImagesToBody)
}
//6 Promise.race应用场景 几张图中只要有一个加载完,就显示在页面中
{
let loadImg = function(src) {
return promise = new Promise(function(resolve, reject) {
let img = document.createElement('img');
img.src = src;
img.onload = function() {
resolve(img) //异步成功执行resolve
}
img.onerror = function() {
reject(img) //异步失败执行reject
}
})
}
// 添加所有图片到页面
let addImagesToBody = function(img) {
document.body.appendChild(img)
}
//Promise.race 返回一个新的promise ,当数组中所有promise实例中只要有一个的状态发生改变 新的promise实例状态就发生变化
Promise.race([
loadImg('http://iconfont.alicdn.com/t/1494395652678.png@200h_200w.jpg'),
loadImg('http://iconfont.alicdn.com/t/1508911280546.jpg@200h_200w.jpg'),
loadImg('http://iconfont.alicdn.com/t/1493708103743.jpeg@200h_200w.jpg')
]).then(addImagesToBody)
}
//7 async await ,
// async表示是一个async函数
//await只能用在这个函数里
//await后面跟着的应该是一个promise对象
//async await是generator函数的语法糖,解决了异步嵌套黑洞的写法问题 真正解决异步问题的是promise
{
async function aa() {
let p1 = function() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('p1')
}, 1000)
})
}
let a1 = await p1(); //a1表示promise返回的结果
console.log('await---' + a1)
}
aa()
}
</script>
</body>
</html>
网友评论