promise
Posted zhihou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了promise相关的知识,希望对你有一定的参考价值。
Promise是什么?
Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行javascript异步编程解决方案之一。这句话说的很明白,Promise是一种用于解决异步问题的思路,方案或者对象方式。在js中,经常使用异步的地方是ajax交互。比如在es5时代,jQuery的ajax的使用success来完成异步的:
$.ajax({
url:‘/xxx‘,
success:()=>{},
error:()=>{}
})
这种方法可以清楚的让读代码的人明白那一部分是Ajax请求成功的回调函数和失败的回调函数,但是问题来了,当一次性需要请求多个接口时,
$.ajax({
url:‘/xxx‘,
success:()=>{
// 第二次
$.ajax({
url:‘/xxx‘,
success:()=>{
// 第三次
$.ajax({
url:‘/xxx‘,
success:()=>{
// 可能还会有
},
error: ()=>{}
})
},
error: ()=>{}
})
},
error: ()=>{}
})
es6时代,promise的出现给异步带来了变革。
Promise提供一个then,来为异步提供回调函数
$.ajax({
url:‘/xxx‘,
}).then(()=>{
//成功的回调
},()=>{
//回调失败
})
Promise的用法
Promise是一个对象,因此,我们使用new的方式新建一个。然后给他传一个函数作为参数,这个函数也有两个参数,一个叫resolve(决定),一个叫reject(拒绝),这两个参数也是函数。我们使用then来调用这个Promise:
const fn=new Promise(function(resolve,reject){
setTimeout(()=>{
let num=Math.ceil(Math.random()*10)
if(num>5){
resolve(num)
}else{
reject(num)
}
},2000)
})
fn.then(res)=>{
console.log(res);
},(err)=>{
console.log(err);
}
Promise的原理
在Promise的内部,有一个状态管理器的存在,有三种状态:pending(在等待…期间),fulfilled,rejected.
(1) promise对象初始化状态为pending。
(2)当调用resolve(成功),会有pending=》fulfilled
(3)当调用reject(失败),会由pending=>rejected
Promise的几种方法
then方法用于注册当前状态变为fulfilled或者reject时回调函数
promise.then(onFulfilled,onRejected);
//onFulfilled用来接收promise成功的值
//onRejected用来接收promise失败的原因
// resolve(成功) onFulfilled会被调用
then方法是异步执行的。
const promise = new Promise((resolve, reject) => {
resolve(‘fulfilled‘); // 状态由 pending => fulfilled
});
promise.then(result => { // onFulfilled
console.log(result); // ‘fulfilled‘
}, reason => { // onRejected 不会被调用
})
// reject(失败) onRejected会被调用
const promise = new Promise((resolve, reject) => {
reject(‘rejected‘); // 状态由 pending => rejected
});
promise.then(result => { // onFulfilled 不会被调用
}, reason => { // onRejected
console.log(rejected); // ‘rejected‘
})
catch
fn = new Promise(function (resolve, reject) {
let num = Math.ceil(Math.random() * 10)
if (num > 5) {
resolve(num)
} else {
reject(num)
}
})
fn.then((res)=>{
console.log(res)
}).catch((err)=>{
console.log(`err==>${err}`)
})
all
var p1=Promise.resolve(1),
p2=Promise.reject(2),
p3=Promise.resolve(3)
Promise.all([p1,p2,p3]).then((res)=>{
console.log(results);
}).catch((err)=>{
console.log(err);
})
大概作为参数的几个promise对象一旦有一个状态为rejected,则all的返回值就是rejected。
当这几个作为参数的函数的返回状态为fulfilled时,至于输出的时间就要看谁跑的慢了:
let p1 = new Promise((resolve)=>{
setTimeout(()=>{
console.log(‘1s‘) //1s后输出
resolve(1)
},1000)
})
let p10 = new Promise((resolve)=>{
setTimeout(()=>{
console.log(‘10s‘) //10s后输出
resolve(10)
},10000)
})
let p5 = new Promise((resolve)=>{
setTimeout(()=>{
console.log(‘5s‘) //5s后输出
resolve(5)
},5000)
})
Promise.all([p1, p10, p5]).then((res)=>{
console.log(res); // 最后输出
})
这段代码运行时,根据看谁跑的慢的原则,则会在10s之后输出[1,10,5]。over,all收工。
race
promise.race()方法也可以处理一个promise实例数组但它和promise.all()不同,从字面意思上理解就是竞速,那么理解起来上就简单多了,也就是说在数组中的元素实例那个率先改变状态,就向下传递谁的状态和异步结果。但是,其余的还是会继续进行的。
let p1 = new Promise((resolve)=>{
setTimeout(()=>{
console.log(‘1s‘) //1s后输出
resolve(1)
},1000)
})
let p10 = new Promise((resolve)=>{
setTimeout(()=>{
console.log(‘10s‘) //10s后输出
resolve(10) //不传递
},10000)
})
let p5 = new Promise((resolve)=>{
setTimeout(()=>{
console.log(‘5s‘) //5s后输出
resolve(5) //不传递
},5000)
})
Promise.race([p1, p10, p5]).then((res)=>{
console.log(res); // 最后输出
})
用js实现一个简单的promise
function Promise(fn){
var status = ‘pending‘;
function successNotify(){
status=‘fulfilled‘//状态变为fulfilled
toDoThen.apply(undefined,arguments) //执行回调
}
function failNotify(){
status=‘rejectd‘ //状态变为rejected
toDoThen.apply(undefined,arguments) //执行回调
}
function toDoThen(){
setTimeout(()=>{ //保证回调是异步执行的
if(status===‘fulfilled‘){
for(let i=0;i<successArray.length;i++){
successArray[i].apply(undefined,arguments) //执行then里面的回掉函数
}
}else if(status===‘rejected‘){
for(let i=0;i<failArray.length;i++){
failArray[i].apply(undefined,arguments) //执行then里面的回掉函数
}
}
})
}
var successArray=[];
var failArray=[];
fn.call(undefined,successNotify,failNotify);
return {
then:function(successFn,failFn){
successArray.push(successFn)
failArray.push(failFn)
return undefined
}
}
}
以上是关于promise的主要内容,如果未能解决你的问题,请参考以下文章