您的位置:首页 > 其它

promise

2015-11-17 17:46 197 查看
有个东西叫回调地狱,promise就是来解决这个的.

看过的一些相关的技术文章

Promise介绍

then和catch方法

all和race方法

一些用法的例子

看过的一些相关的技术文章

http://liubin.github.io/promises-book/

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

Promise介绍

Promise介绍

以前写一些异步的东西,都使用回调函数来执行的,这样的写法让人看起来很不舒服

比如写一个隔几秒就执行的一个回调的东西,然后在回调的时候,开始下一个异步

setTimeout(function(){
console.log(11111)
setTimeout(function(){
console.log(22222)
setTimeout(function(){
console.log(33333)
setTimeout(function(){
console.log(44444)
setTimeout(function(){
console.log(55555)
},5000)
},4000)
},3000)
},2000)
},1000)


这代码开起来维护起来都会很麻烦的,后来的后来,es6支持原生的Promise,jquery支持Deferred,Promise后,异步问题就容易多了

一个原生的Promise实现上面的代码

function setTime(t){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve();
},t)
});
}
setTime(1000)
.then(function(){
console.log(11111)
return setTime(1000);
})
.then(function(){
console.log(22222)
return setTime(2000);
})
.then(function(){
console.log(33333)
return setTime(3000);
})
.then(function(){
console.log(44444)
return setTime(4000);
})
.then(function(){
console.log(55555)
})


什么是Promise?

Promise是抽象异步处理对象以及对其进行各种操作的组件。 其详细内容在接下来我们还会进行介绍,Promise并不是从JavaScript中发祥的概念。

Promise最初被提出是在 E语言中, 它是基于并列/并行处理设计的一种编程语言。

Promise的基本用法

new Promise(function(resolve, reject) { ... })

参数

带有 resolve 、reject两个参数的函数对象。 第一个参数用在处理执行成功的场景,第二个参数则用在处理执行失败的场景。 一旦我们的操作完成即可调用这些函数。

resolve是实例化后Promise用then里面调用的函数

reject是实例化后Promise用catch里面调用的函数

实例化的Promise有3个状态 :等待(pending)、已完成(fulfilled)、已拒绝(rejected)

实例化的Promise的状态,只可能从“等待”转到“完成”态或者“拒绝”态,不能逆向转换,同时“完成”态和“拒绝”态不能相互转换

then和catch方法

then方法

then方法负责添加针对已完成的处理函数,同一个实例化后的Promise可以有多个then,then方法默认会返回当前的Promise,也可以自己重新实例化一个新的Promise

then方法对应实例化时候,function的resolve

catch方法

catch方法负责添加针对拒绝状态下处理函数,同一个实例化后的Promise可以有多个catch,catch方法默认会返回当前的Promise,也可以自己重新实例化一个新的Promise

catch方法对应实例化时候,function的resolve

一个例子

new Promise(function(resolve,rejected){
var img = new Image();
img.src="http://www.paipai.com/xx.jpg";   //这个会失败
//img.src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png" //这个会成功
img.onload = function(){
resolve();
}
img.onerror = function(){
rejected();
}
})
.then(function(){
console.log("图片加载成功!")
})
.catch(function(){
console.log("图片加载失败!")
})


all和race方法

all方法

Promise.all 接收一个 promise对象的数组作为参数,当这个数组里的所有promise对象全部变为resolve或reject状态的时候,它才会去调用 .then 方法

这个比较好用,当有多个请求的时候,一起请求,一起处理

return new Promise(function(resolve,rejected){
setTimeout(function(){
resolve();
},t)
})
}
Promise.all([setTime(1000),setTime(5000)])
.then(function(){
console.log("5秒后打印!");
})


race方法

只要有一个promise对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。

function setTime(t){
return new Promise(function(resolve,rejected){
setTimeout(function(){
resolve();
},t)
})
}
Promise.race([setTime(1000),setTime(5000)])
.then(function(){
console.log("1秒后打印!");
})


一些用法的例子

Promise并非所有的浏览器都支持,比如ie就是不支持,幸好jquery也有类似的用法

1.一个异步里面接着另一个异步

原生Promise的实现

function setTime(t){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve();
},t)
});
}
setTime(1000)
.then(function(){
console.log(11111)
return setTime(1000);
})
.then(function(){
console.log(22222)
return setTime(2000);
})
.then(function(){
console.log(33333)
return setTime(3000);
})
.then(function(){
console.log(44444)
return setTime(4000);
})
.then(function(){
console.log(55555)
})


jquery的实现

function setTime(t){
return $.Deferred(function(dtd){
setTimeout(function(){
dtd.resolve();
},t);
});
}

setTime(2000)
.then(function(){
console.log(11111)
return setTime(1000);
})
.then(function(){
console.log(22222)
return setTime(2000);
})
.then(function(){
console.log(33333)
return setTime(3000);
})
.then(function(){
console.log(44444)
return setTime(4000);
})
.then(function(){
console.log(55555)
})


2.多个ajax串行的请求(满足后面的请求依赖前面的请求的情况)

原生的实现

chorme浏览器可以直接在博客园下的console直接运行,如果接口都还在的

var urls = {
sideRight : "http://www.cnblogs.com/aggsite/SideRight",
userStats : "http://www.cnblogs.com/aggsite/UserStats"
}
function get(URL){
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject();
}
};
req.onerror = function () {
reject();
};
req.send();
});
}
get(urls.sideRight)
.catch(function(){
console.log("请求失败!!!");
})
.then(function(html){
console.log(html);
console.log("-----------------------------------------------------------")
return get(urls.userStats);
})
.catch(function(){
console.log("请求失败!!!");
})
.then(function(html){
console.log(html)
})


jquery的实现

var urls = {
sideRight : "http://www.cnblogs.com/aggsite/SideRight",
userStats : "http://www.cnblogs.com/aggsite/UserStats"
}

$.ajax({
url      : urls.sideRight,
type     : "get",
dataType : "html"
})
.fail(function(){
console.log("请求失败!!!");
})
.done(function(html){
console.log(html)
console.log("-----------------------------------------------------------")
return $.ajax({
url      : urls.userStats,
type     : "get",
dataType : "html"
});
})
.fail(function(){
console.log("请求失败!!!");
})
.done(function(html){
console.log(html)
})


3.多个请求并行发送(适用于多个请求才能渲染出一个页面的情况)

原生Promise实现

var urls = {
sideRight : "http://www.cnblogs.com/aggsite/SideRight",
userStats : "http://www.cnblogs.com/aggsite/UserStats"
}
function get(URL){
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(URL);
}
};
req.onerror = function () {
reject(URL);
};
req.send();
});
}

Promise.all([get(urls.sideRight),get(urls.userStats)])
.then(function(htmlArr){
console.log(htmlArr[0])
console.log("-----------------------------------------------------------")
console.log(htmlArr[1])
})
.catch(function(url){
console.log(url+"  : 失败了");
})


jquery实现

var urls = {
sideRight : "http://www.cnblogs.com/aggsite/SideRight",
userStats : "http://www.cnblogs.com/aggsite/UserStats1"
}

var $ajax1 = $.ajax({
url      : urls.sideRight,
type     : "get",
dataType : "html"
})

var $ajax2 = $.ajax({
url      : urls.userStats,
type     : "get",
dataType : "html"
})

$.when($ajax1,$ajax2)
.done(function(response1Arr,response2Arr){
console.log(response1Arr[0]);
console.log("----------------------------");
console.log(response2Arr[1])
})
.fail(function(res){
console.log("请求失败了")
});


注:当任意一个请求失败的时候,都会进入fail
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: