Promise理解使用
promise 是什么
简单理解:promise是用于解决异步编程的一种新的解决方案,prominse对象用于表示一个异步操作最终完成的结果值;
具体体现:
语法 : promise是一个构造函数 ,可以用于实例化一个对象
功能: 通过调用Promise构造函数可以实例化一个封装有异步操作的对象,并且此对象可以获取异步操作的成功/失败的结果值;
promise执行流程:
何时使用Promise
前端程序需要执行异步操作,并依赖其结果进行下一步操作时需要使用Promise。
promise的作用是什么
用于对异步操作进行指定相应的回调函数,使用Promise对象之后可以采用链式调用的方式整理代码结构,避免执行多个异步任务而造成层层嵌套的回调函数,提高代码运行效率以及可读性。
为什么要使用Promise
1、使用promise能够让指定回调函数的方式更加灵活。使用promise可以在启用异步任务之后在进行指定回调函数。不使用Promise就只能在执行异步任务之前指定回调函数且只能指定一次
2、支持链式调用,有效解决回调地狱问题。
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult);
}, failureCallback);
}, failureCallback);
}, failureCallback);
// 使用Promise之后 采用链式调用避免死亡回调.
doSomething().then(function(result) {
return doSomethingElse(result);
})
.then(function(newResult) {
return doThirdThing(newResult);
})
.then(function(finalResult) {
console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);
使用Promise
promise使用代码示例
var newPromise = new Promise((resolve, reject) => {
// // 此处封装异步操作代码
// // 执行异步操作
// resolve(value); //成功执行操作
// reject(reason); // 失败执行操作
setTimeout(() => {
var data = 0;
if (data == 1) {
resolve("进行成功的操作");
} else {
reject("执行失败之后的操作");
}
}, 0);
});
newPromise.then(
(value) => {
// 成功执行操作
},
(reason) => {
// 失败执行操作
}
);
// 如果需要执行多个操作可以多次执行then指定回调函数
newPromise.then(
(value) => {
// 成功执行操作
},
(reason) => {
// 失败执行操作
}
);
newPromise.catch(resson={
// 失败执行操作
});
Promise的属性
promise对象含有两种属性
PromiseState:表示异步操作的状态共分为 pending,resolve,reject
PromiseResult:表示异步操作的结果值
promise的状态及其状态改变:
promise状态在初始化时的默认赋值为pending,可以并且只能改变一次
PromiseState:pending=>resolve 成功
PromiseState:pending=>reject 失败
promise的属性是promise对象的私有属性,其属性的改变只能由promise对象内部进行改变;
其中PromiseState的状态改变的共有三种方式
resolve, 成功时修改
reject 失败是修改
throw 抛出异常是修改
PromiseResult属性值会根据PromiseState改变时会随之改变
if(PromiseState==='pending'){
PromiseResult=undefined;
}
else if(PromiseState==='reslove'){
PromiseResult="成功的结果值"
}
else if(PromiseState==='reject'){
PromiseResult="失败的原因"
}
promise的API的调用
-
Promise构造函数
使用示例:new Promise(executor) // 参数 executor 双参数的执行执行器函数,通过此函数可以用来封装相应的异步操作,执行器的代码执行顺序为同步执行 示例 : const myFirstPromise = new Promise((resolve, reject) => { // do something asynchronous which eventually calls either: // // resolve(someValue) // fulfilled // or // reject("failure reason") // rejected }); // 执行器参数说明 // resolve 异步操作执行成功调用的执行操作 // rejected 异步操作执行失败后的执行操作 // 具体的操作将由then/catch 方法对其进行指定
-
Promise.prototype.then
对Promise对象中封装的异步操作指定成功/失败的回调函数
PromiseState语法 p.then(onFulfilled[, onRejected]); p.then(value => { // fulfillment }, reason => { // rejection }); 参数说明 onFulfilled/onResloved 异步操作成功操作指定的回调函数 onRejected 异步操作执行失败 指定的回调函数 返回值说明 then 方法默认返回一个Promise对象,Promise状态取决于指定的回调函数。 返回一个Promise对象 属性值说明 共存在两种情形 no1 onFulfilled/onResloved返回数值为非Promise 此时 PromiseState=reslove PromiseResult=返回值 no2 onFulfilled/onResloved返回Promise对象 此时 PromiseState=返回的Promise的对象的状态 PromiseResult=返回的Promise的对象的结果值 no3 onRejected 执返回数值为非Promise 此时 PromiseState=reslove PromiseResult=返回值 no4 onRejected 返回Promise对象 此时 PromiseState=返回的Promise的对象的状态 PromiseResult=返回的Promise的对象的结果值 no5 出现异常 此时 PromiseState=rejcted PromiseResult=错误原因
说明 因为then方法返回Promise对象 ,then()执行后可以继续链式调用相应的Promise方法
-
Promise.prototype.catch
对Promise对象封装的异步操作执行失败/异常时相应的回调函数
p.catch(onRejected); //示例 p.catch(function(reason) { reason失败的原因 // 拒绝 }); 参数说明 onRejected 异步操作拒绝时指定的回调操作 返回值 Promise对象 其状态值参考 then的 no3 ,no4返回状态值
-
Promise.prototype.finally
finally()是对前面封装有异步操作的方法无论成功/拒绝都会执行的方法
p.finally(function() { // 返回状态为(resolved 或 rejected) });
-
Promise.reslove
*Promise.resolve(value)*方法 返回一个以给定值解析后的Promise对象,如果参数本身就是一个
Promise
对象,则直接返回这个Promise
对象。其返回的Promise状态是由参数决定的 由于Promise的状态只能改变一次所以 then指定的回调函数只能被执行一个Promise.resolve("Success").then(function(value) { console.log(value); // "Success" }, function(value) { // 不会被调用 });
-
Promise.reject
Promise.reject() 方法返回一个带有拒绝原因的
Promise
对象。Promise.reject(new Error('fail')).then(function() { // not called }, function(error) { console.error(error); // Stacktrace });
-
Promise.all/any
Promise.all(iterable) 给定一个数组集合,只有当数组集合中所有的Promise封装的异步操作成功或者一个异步操作被拒绝才进行回调函数的指定操作。其返回Promsie对象是由传入参数决定
当参数不包含Promise对象时 返回成功的Promise对象, 当参数包含Promsse对象时,返回的Promise对象的状态值由Promise对象的封装的异步操作结果决定。 // var p1 = Promise.resolve(3); var p2 = 1337; var p3 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'foo'); }); Promise.all([p1, p2, p3]).then(values => { console.log(values); // [3, 1337, "foo"] }); // 注意 此时的then方法中的value是包含所有结果的数组 。 简单理解 所有成功才成功 有一个失败即为失败
promsie.any ()与promise.all()方法刚好相反
-
Promise.race
Promise.race(iterable) iterable封装有异步操作的Promise的数组集合,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
const promise1 = new Promise((resolve, reject) => { setTimeout(resolve, 500, 'one'); }); const promise2 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'two'); }); Promise.race([promise1, promise2]).then((value) => { console.log(value); // Both resolve, but promise2 is faster }); // expected output: "two"
promise的几个关键问题
-
如何改变Promise状态
共计三种方式 reslove(value),reject(reason),throw
-
Promise指定多个成功/失败的回调函数都会执行吗
当Promise的状态改变时都会调用
-
Promise状态改变和指定回调函数先后顺序
都有可能,Promise通过调用异步队列将改变状态放在前面然后在执行指定的回调函数
-
Promise如何串联多个异步操作任务
通过then方式的链式调用
async/await与Promise的关系
什么是async/await
async/await 是进行异步编程的一种全新的方式,是在Promise的基础上对异步编程进一步简化。
其中async function 默认将方法返回对象封装成Promise对象 ,await则只能使用在async 修饰的function中
async/await使得异步代码看起来像同步代码。
Promise和async/await 均是是非阻塞的
假设函数getJSON返回值是 Promise,并且 Promise resolves 有一些JSON 对象。我们只想调用它并且记录该JSON并且返回完成。
1)使用Promise:
const makeRequest = () =>
getJSON().then(data => {
console.log(data)
return "done"
})
makeRequest()
const makeRequest = async () => {
// await getJSON()表示console.log会等到getJSON的promise成功reosolve之后再执行。
console.log(await getJSON)
return "done"
}
makeRequest()
小思考
await 和then使用起来有什么共同点和不同点
参考文档链接
JSON().then(data => {
console.log(data)
return “done”
})
makeRequest()
const makeRequest = async () => {
// await getJSON()表示console.log会等到getJSON的promise成功reosolve之后再执行。
console.log(await getJSON)
return "done"
}
makeRequest()
小思考
await 和then使用起来有什么共同点和不同点
## 参考文档链接
[Promsie参考文档)](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise)