promise的简单理解
promise是一个类,在通过new关键字创建promise对象时,需要传入一个回调函数,称之为executor,这个回调函数会被立即执行,并且传入另外的2个回调函数resolve和reject。当调用resolve回调函数时,会执行promise对象的then方法传入的回调函数,当回调reject回调函数时,会执行promise对象的catch方法传入的回调函数。
//promise的基本使用
const promise = new Promise((resolve,reject) => {
console.log("promise被执行了~");
resolve();
//reject()
})
promise.then(() => {
console.log("resolve被回调了~")
})
promise.catch() => {
console.log("reject被回调了~")
}
//还可以将then和catch直接写在new Promise的后面
//promise的链式调用的写法
const promise1 = new Promise((resolve,reject) => {
console.log("promise1被执行了");
}) .then((res) => {
console.log("resolve回调了~")
},(err) => {
console.log("reject回调了~")
}).catch(err) => {
console.log("异常在这里被捕获~")
}
promise的3种状态
在promise的使用过程中,可以将promise划分为3个状态:
**pending:**待定,初始化状态,即没有被兑现也没有被拒绝,当promise被执行时,也就是executor被执行时,处于这个状态
**fulfilled:**已兑现,意味着操作成功了,执行了resolve时,处于这个状态
**rejected:**已拒绝,意味着操作失败,执行了reject时,处于这个状态
executor
executor是在new Promise时需要传入的一个回调函数,这个回调函数会被立即执行的,并且传入2个参数resolve和reject。
通常在executor中去确定promise的状态的。如果执行了resolve,就是进入了fulfilled状态,如果执行了reject就是进入了rejected状态,这里需要注意的是,一旦promise的状态被确定下来了,promise就会被锁死。也就是说,状态一经确定就无法再进行修改。
如果在调用resolve时,resolve传入的值不是一个promise,那么当前的promise的状态就是fulfilled,这个时候再去调用reject是没有任何作用的,这就是因为配偶米色的状态一经确定就无法修改的原因。反之,在reject中也是一样的道理。但是如果在resolve或者reject中传入的值是一个promise的话,那么状态的确定会进行移交,当前promise的状态会在传入的这个promise中去决定。
resolove参数不同的情况:
情况一:resolve如果传入了一个普通的值或者对象的,那么这个值或者对象会作为then的回调函数的最 终结果
情况二:resolve如果传入的是另一个promise,那么这个新的promise会决定原来的promise的状态,称之为promise的状态的移交
情况三:如果resolve传入了一个对象,并且这个对象自己实现了then方法,那么会执行这个对象的then方法,并且根据对象的then方法的结果来决定promise的状态的
//情况一:传入一个普通的值或者对象
let num = 1
const obj = {
name:'obj',
age:18
}
const promise = new Promise((resolve,reject) => {
resolve(num)
//resolve(obj)
}).then( res => {
console.log(res)//这里会将num的值和obj的对象的值打印出来
})
//情况二:传入一个promise
const newPromise = new Promise((resolve, reject) => {
// resolve("newPromise")
reject("error message")
})
new Promise((resolve, reject) => { //这个promise的执行结果的状态最终是由传入的promise来决定的
resolve(newPromise)
}).then( res => {
console.log(res)
}).catch(err => {
console.log(err)
})
//情况三:传入的对象自行实现了then方法
const obj = {
name: 'obj',
age: 18,
then(resolve, reject) {
// resolve('我是obj的then方法resolve')
reject('我是obj的then方法中的reject')
}
}
const promise = new Promise((resolve, reject) => {//这里的promise的then方法执行的是传入对象自行实现的then方法
resolve(obj)
}).then(res => [
console.log(res)
]).catch(err => {
console.log(err)
})
then方法
then方法是promise对象上的一个方法,实际就是放在promise的原型上的Promise.prototype.then,then可以同时接受2个参数,一个是fulfilled的回调函数,一个是rejected的回调函数。
const promise = new Promise((resolve, reject) => {
// resolve("resolve")
reject("reject")
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
//相当于下面的代码
promise.then(res => {
console.log(res)
}).catch(err => [
console.log(err)
])
then方法是可以多次进行调用的,当promise的状态的为fulfilled的时候,所有调用的then方法都是会执行的
const promise = new Promise((resolve, reject) => {
resolve("resolve")
})
promise.then(res => {
console.log("then1:",res)
})
promise.then(res => [
console.log("then2:",res)
])
promise.then(res => [
console.log("then3:",res)
])
then也是有返回值的,then的返回值是一个promise,所以是可以进行链式调用的。
then的返回值的promise的状态:
当then方法中的回调函数本身在执行时是处于pending状态的;
当then方法中的回调函数返回一个结果时,处于的是fulfilled状态,并且会将结果作为resolve的参数来使用;
当then方法throw一个异常时,就处于rejected的状态
const promise = new Promise((resolve, reject) => {
resolve("resolve")
})
//如果是返回了一个普通的值,包括undefined,会将这个返回的值作为resolve的参数,传递到下一个then方法中去
promise.then(res => {
return "返回了一个普通的值"
}).then(res => {
console.log(res)
})
//如果返回的是一个promise的话,下一个then方法会去执行返回的这个promise的resolve函数
promise.then(res => {
return new Promise((resolve, reject) => {
resolve("new create promise")
})
}).then(res => {
console.log(res)
})
//如果返回的是一个对象,并且返回的这个对象如果也自行实现了then方法的话,下一个then方法会去执行返回对象的then方法
promise.then(res => {
return {
then(resolve, reject) {
resolve("返回对象的then方法")
}
}
}).then(res => {
console.log(res)
})
catch
catch方法也是promise对象的方法,也是放在promise的原型上的Promise.prototype.catch,catch方法也是可以进行多次调用的,每次执行的时候都是会传入对应的reject的回调函数的,当promise的状态为rejected时,这些调用的catch都是会进行执行的。
const promise = new Promise((resolve, reject) => {
reject("error message")
})
promise.catch(err => {
console.log("catch1:",err)
})
promise.catch (err => {
console.log("catch2:",err)
})
promise.catch (err => {
console.log("catch3:",err)
})
catch的返回值也是一个promise,所以可以进行链式的调用,也可以在catch之后继续调用then
const promise = new Promise((resolve, reject) => {
reject("error message")
})
//如果返回的是一个普通值的话,包括undefined,会将返回的这个普通值作为resolve的参数传递至下一个then中去
promise.catch(err => {
return "返回一个普通的值"
}).then(res => {
console.log(res)
})
//如果返回值是一个promise,这个promise还调用了reject回调,那么就会将这个promise的reject传递至下一个catch中去执行
promise.catch(err => {
return new Promise((resolve, reject) => {
reject("返回值的promise")
})
}).catch(err => {
console.log(err)
})
finally
finally是ES9新增的一个特性,它表示为无论promise最终处于fulfilled状态还是rejected状态,都是会执行finally的回调的。
const promise = new Promise((resolve, reject) => {
// resolve("resolve")
reject("error message")
})
promise.then(res => {
console.log(res)
}).catch(err => {
console.log(err)
}).finally(() => {
console.log("我是finally的执行函数")
})
上面说到的都是promise的对象方法,是放在promise原型上的方法,接下来就来说下Promise的类方法。
Promise的类方法—resolve
如果有一个现成的内容,希望将这个现成的内容转换为promise的话,就可以使用promise的类方法Promise.resolve来进行。Promise.resolve就相当于是new Promise的操作,并且转换完成之后调用执行的是resolve。
Promise.resolve("promise").then(res => {
console.log(res)
})
//相当于执行了下面的代码
new Promise((resolve, reject) => {
resolve("promise")
}).then(res => {
console.log(res)
})
类方法resolve的参数
//如果是一个普通的值或者一个对象的话,会将这个值或者对象作为promise的resolve的参数
const obj = {
name:'obj'
}
const promise = Promise.resolve(obj)
promise.then(res => {
console.log(res)
})
//如果参数是一个promise对象的话,会直接将这个promise中的resolve或者reject传递到当前的转换的promise对象中去执行,并且进行一个状态的移交
const promise = Promise.resolve(new Promise((resolve, reject) => {
// resolve("resovle")
reject("reject")
}))
promise.then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
Promise类方法—reject
类方法reject跟resolve基本是一致的,只不过是将转换的promise的状态修改为了rejected,这里不再具体的说明了,可以参照上面的resolve方法去理解和使用
Promise.reject("promise").catch(err => {
console.log(err)
})
//相当于下面的代码
new Promise((resolve,reject) => {
reject("promise")
})
Promise类方法—all
Promise.all方法的作用是将多个promise包裹后形成一个新的promise,新合成的promise的状态由包裹的所有的promise来共同决定,如果包裹的所有的promise的状态都为fulfilled时,新合成的promise的状态就为fulfilled,并且将所有包裹的promise返回值组成一个数组,如果包裹的promise其中的一个promise的状态为rejected时,新合成的promise的状态就为rejected,并且将第一个状态为rejected的promise的reject的返回值作为参数进行调用。
但是all方法存在一个缺陷,就是当有一个promise处于rejected状态时,新合成的promise就会立即变为rejected状态,那么对于其他的fulfilled状态,以及依然处于pending状态的promise是无法获取到对应的结果的。
const promise1 = new Promise((resolve, reject) => {
resolve("promise1 resolve")
// reject("promise1 reject")
})
const promise2 = new Promise((resolve, reject) => {
resolve("promise2 resolve")
})
const promise3 = new Promise((resolve, reject) => {
resolve("promise3 resolve")
// reject("promise3 reject")
})
Promise.all([promise1, promise2, promise3]).then(res => {
console.log(res)
}).catch(err => [
console.log(err)
])
Promise类方法—allSettled
为了解决all方法存在的缺陷,在ES11中新增了allSettled方法,这个方法会在包裹的所有的promise全部拥有状态后才会让新合成的promise拥有最终的一个状态,并且无论包裹的promise的fulfilled状态还是rejected状态,最终新合成的状态一定是fulfilled的。即便包裹的所有的promise都是rejected状态,最终新合成的promise也是会进入fulfilled状态的。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve("p1 resolve")
reject("p1 reject")
}, 1000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
//resolve("p2 resolve")
reject("p2 reject")
}, 2000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve("p3 resolve")
reject("p3 reject")
}, 3000);
})
Promise.allSettled([p1, p2, p3]).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
allSettled的返回结构是一个数组,数组中存放的每一个promise的返回结果,每一个promise返回的结果会对应一个对象,这个对象包含了对应promise的status状态或者value值或者reason原因
Promise类方法—race
race方法是当包裹的多个promise中,只要有其中一个有了结果就使用最先获取到结果的promise的状态来决定新合成的promise的状态。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve("p1 resolve")
reject("p1 reject")
}, 1000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve("p2 resolve")
reject("p2 reject")
}, 500);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve("p2 resolve")
reject("p3 reject")
}, 2000);
})
Promise.race([p1, p2, p3]).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
Promsie类方法—any
any方法和race方法是类似的,any方法是会等到其中一个promise的状态为fulfilled的时候才会去决定新的promise的状态的,但是如果所有的promise都是rejected状态的话,那么any会等到所有的promise都变为了rejected状态后报错。
目前这个any方法仍然是一个实验性质的方法,所以这里不再做说明解释,需要学习可自行在MDN上查看相应文档。
以上就是我个人对promise基础性知识的一个理解,如有错误还请码友们指出,我及时改正,也多多学习。