首页 前端知识 12.关于JS中的promise理解以及使用

12.关于JS中的promise理解以及使用

2024-03-11 10:03:45 前端知识 前端哥 197 703 我要收藏

一、什么是promise

Promise是一种异步编程的解决方案,用于处理异步操作并返回结果,从语法上看它是一个构造函数,从功能上看它是用来封装一个异步操作并可以获取它成功/失败的结果值。

1.概念

简单来说就是一个容器,里面保存着未来才会结束的事件( 通常是一个异步操作 )的结果。从语法上来说,Promise是个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作(定时器、ajax请求等)都可以用同样的方法进行处理。

2.特点

1、promise有三种状态 进行中(pending)、已成功(fulfilled)、已失败(rejected)、且promise必然处在这三种状态之中

2、一旦状态改变,就不会再改变,任何时候都可以得到这个结果。状态改变只有两种状态从pending变为fulfilled和从pending变为rejected。

二、用法

1.基本用法

// Promise构造函数接受一个函数(执行器函数)作为参数,
// 该函数的两个参数分别是resolve和reject。它们是两个函数,
// 由 JavaScript 引擎提供,不用自己部署。
const promise = new Promise(function (resolve, reject) {
// ... some code
if (/* 异步操作成功 */) {
// 在异步操作成功时调用,并将异步操作的结果,作为参数value传递出去;
resolve(value);
} else {
// 在异步操作失败时调用,并将异步操作报出的错误,作为参数error/reason传递出去。
reject(error);
}
});
复制

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

promise.then(function(value) {
// success
}, function(error) {
// failure
});
复制

then方法可以接受两个回调函数作为参数。

  • 第一个回调函数是Promise对象的状态变为resolved时调用。
  • 第二个回调函数是Promise对象的状态变为rejected时调用。
// 创建一个新的p对象promise
const p = new Promise((resolve, reject) => { // 执行器函数
// 执行异步操作任务
setTimeout(() => {
const time = Date.now()
// 如果当前时间是偶数代表成功,否则失败
if (time % 2 == 0) {
// 如果成功,调用resolve(value)
resolve('成功的数据,time=' + time)
} else {
// 如果失败,调用reject(reason)
reject('失败的数据,time=' + time)
}
}, 1000);
})
p.then(
value => { // 接收得到成功的value数据 onResolved
console.log('成功的回调', value) // 成功的回调 成功的数据
},
reason => { // 接收得到失败的reason数据 onRejected
console.log('失败的回调', reason) // 失败的回调 失败的数据
}
)
复制

2.Promise.prototype.then 方法

(onResolved, onRejected) => {}   指定两个回调(成功+失败)

onResolved 是成功的回调函数,onRejected是失败的回调函数

3.Promise.prototype.catch 方法

onRejected 函数: 失败的回调函数 (reason) => {}

catch是then的语法糖,相当于then(undefined, onRejected)

4.Promise.resolve方法  Promise.resolve(value) => {}

let p1 = Promise.resolve(521);
console.log(p1); // Promise {<fulfilled>: 521}
复制

返回一个成功/失败的 promise 对象

value:传入一个promise或者成功的数据

如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果

let p2 = Promise.resolve(new Promise((resolve, reject) => {
// resolve('OK'); // 成功的Promise
reject('Error');
}));
console.log(p2);
p2.catch(reason => {
console.log(reason);
})
复制

5.Promise.reject 方法: Promise.resolve(reason) => {}

返回一个失败的 promise 对象

let p = Promise.reject(521);
let p2 = Promise.reject('iloveyou');
let p3 = Promise.reject(new Promise((resolve, reject) => {
resolve('OK');
}));
console.log(p);
console.log(p2);
console.log(p3);
复制

 

Promise.resolve() / Promise.reject() 方法就是一个语法糖,用来快速得到Promise对象

6. Promise.all 方法: Promise.all(iterable) => {}

  • iterable:包含 n 个 promise 的可迭代对象,如 Array 或 String
  • 返回一个新的 promise,只有所有的 promise都成功才成功,只要有一个失败了就直接失败。
let p1 = new Promise((resolve, reject) => {
resolve('OK');
})
let p2 = Promise.resolve('Success');
let p3 = Promise.resolve('Oh Yeah');
const result = Promise.all([p1, p2, p3]);
console.log(result);
result.then(res => {
console.log(res, '打印结果');
})
复制

且用then回调函数参数也为数组

let p1 = new Promise((resolve, reject) => {
resolve('OK');
})
let p2 = Promise.reject('Error');
let p3 = Promise.resolve('Oh Yeah');
const result = Promise.all([p1, p2, p3]);
console.log(result);
result.then(res => {
console.log(res);
}).catch(msg => {
console.log(msg);
})
复制

 

当有一个不成功时就会失败

Promise.all( ).then( )适用于处理多个异步任务,且所有的异步任务都得到结果时的情况。

使用场景:用户点击按钮,会弹出一个弹出对话框,对话框中有两部分数据呈现,这两部分数据分别是不同的后端接口获取的数据。弹框弹出后的初始情况下,就让这个弹出框处于数据加载中的状态,当这两部分数据都从接口获取到的时候,才让这个数据加载中状态消失。让用户看到这两部分的数据。

7. Promise.race方法:Promise.race(iterableiterableiterableiterableiterableiterableiterable) => {}

  • iterable:包含 n 个 promise 的可迭代对象,如 Array 或 String
  • 返回一个新的 promise, 第一个完成的 promise的结果状态就是最终的结果状态。
// 谁先完成就输出谁(不管是成功还是失败)
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000)
})
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)
const pRace = Promise.race([p1, p2, p3])
pRace.then(
value => {
console.log('race onResolved()', value)
},
reason => {
console.log('race onRejected()', reason)
}
)
复制

类似于Promise.all() ,区别在于 它有任意一个返回成功后,就算完成,但是 进程不会立即停止

使用场景:把异步操作和定时器放到一起,如果定时器先触发,认为超时,告知用户

8.promise关键点

如何改变promise的状态:通过resolve(value)、reject(reason)、 抛出异常 可以改变promise的状态

const p = new Promise((resolve, reject) => {
//resolve(1) // promise变为resolved成功状态
//reject(2) // promise变为rejected失败状态
throw new Error('出错了') // 抛出异常,promise变为rejected失败状态,reason为抛出的error
})
p.then(
value => { },
reason => { console.log('reason', reason) }
)
复制

 

9.promise链式调用 

promise 的 then()返回一个新的 promise, 可以开写成 then()的链式调用

new Promise((resolve, reject) => {
setTimeout(() => {
console.log('执行任务1(异步)')
resolve(1)
}, 1000)
}).then(
value => {
console.log('任务1的结果', value)
console.log('执行任务2(同步)')
return 2 // 同步任务直接return返回结果
}
).then(
value => {
console.log('任务2的结果', value)
return new Promise((resolve, reject) => { // 异步任务需要包裹在Promise对象中
setTimeout(() => {
console.log('执行任务3(异步)')
resolve(3)
}, 1000)
})
}
).then(
value => {
console.log('任务3的结果', value)
}
)
复制

链式调用的原理:

因为then方法也会返回一个新的Promise, 然后这个Promise会根据它接收的参数,来决定状态, 如果接收到的不是一个Promise, 那么它就自动置为fullfill, 如果接收到的参数是Promise, 那么就将它的resolve函数放在接收到的Promise中的then方法执行, 所以就保证了只有接收到的参数的那个Promise执行完, 返回的的Promise才会执行,也就形成链式调用的过程

转载请注明出处或者链接地址:https://www.qianduange.cn//article/3577.html
标签
评论
发布的文章

jQuery之宽高

2024-04-05 09:04:19

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!