一、理解promise
Promise将异步执行的程序变成同步执行,所谓的在开发中解决回调嵌套的问题
Promise 是异步编程的一种解决方案
从语法上讲,promise是一个对象
从它可以获取异步操作的消息
从本意上讲,它是承诺,承诺它过一段时间会给你一个结果
创造promise实例后,它会立即执行
Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值
二、promise三种状态
待定(pending):初始状态,既没有被兑现,也没有被拒绝。
已兑现(fulfilled):操作成功。
已拒绝(rejected):操作失败。
promise状态一旦改变,就不会再变。
一个 Promise 对象代表一个在这个 promise 被创建出来时不一定已知的值。它让您能够把异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。 这样使得异步方法可以像同步方法那样返回值:异步方法并不会立即返回最终的值,而是会返回一个 Promise ,以便在未来某个时候把值交给使用者。
待定状态的 Promise 对象要么会通过一个值被兑现(fulfilled),要么会通过一个原因(错误)被拒绝(rejected)。当这些情况之一发生时,我们用 promise 的 then 方法排列起来的相关处理程序就会被调用。如果 promise 在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序就会被调用,因此在完成异步操作和绑定处理方法之间不会存在竞争状态。
三、Promise原理
promise对象是由关键字 new 及其构造函数来创建的。该构造函数会把一个叫做“处理器函数”(executor function)的函数作为它的参数。这个“处理器函数”接受两个函数resolve 和 reject 作为其参数。当异步任务顺利完成且返回结果值时,会调用 resolve 函数;而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用 reject 函数。
四、promise解决回调嵌套问题
4.1、正常执行
function one (){ return 'i am one'} function two (){ return 'i am two'} function three (){ return 'i am three'} function run (){ console.log(one()) console.log(two()) console.log(three()) } run() // i am one // i am two // i am three
4.2、出现问题
function one (){ return 'i am one'} function two (){ setTimeout(()=>{ return 'i am two' }, 2000) } function three (){ return 'i am three'} function run (){ console.log(one()) console.log(two()) console.log(three()) } run() // i am one // undefined // i am three
4.3、promise解决问题
function one (){ return 'i am one'} function two (){ return new Promise((resolve, reject)=>{ setTimeout(()=>{ resolve('i am two') }, 2000) }) } function three (){ return 'i am three'} function run (){ console.log(one()) console.log(two()) console.log(three()) } run() // i am one // Promise {<pending>} // i am three
4.4、配合 async await
function one (){ return 'i am one'} function two (){ return new Promise((resolve, reject)=>{ setTimeout(()=>{ resolve('i am two') }, 2000) }) } function three (){ return 'i am three'} async function run (){ console.log(one()) console.log(await two()) console.log(three()) } run() // i am one // Promise {<pending>} // i am two // i am three
五、Promise方
5.1、Promise.all()
const createPromise = (delay, flag = true)=>{ return new Promise((resolve, reject)=>{ setTimeout(()=>{ flag ? resolve(console.log(`成功${delay}`)) : reject(console.log(`失败${delay}`)) },delay) }) } //----失败------- createPromise(500, false) //失败500 //-----成功---------- createPromise(500) 成功500 Promise.all(createPromise(1000), createPromise(2000), createPromise(3000)) .then((res)=>{ console.log('成功', res) }) .catch((err)=>{ console.log('失败', err) }) // 成功1000 // 成功2000 // 成功3000
5.2、Promise.allSettled()
5.3、Promise.any()
5.4、Promise.prototype.catch()
5.5、Promise.prototype.finally()
5.6、Promise.race() 谁快谁先执行
const createPromise = (delay, flag = true)=>{ return new Promise((resolve, reject)=>{ setTimeout(()=>{ flag ? resolve(console.log(`成功${delay}`)) : reject(console.log(`失败${delay}`)) },delay) }) } Promise.race(createPromise(3000), createPromise(2000, false), createPromise(1000)) .then((res)=>{ console.log('成功', res) }) .catch((err)=>{ console.log('失败', err) }) // 成功1000 // 失败2000 // 成功3000
5.7、Promise.reject()
5.8、 Promise.resolve()
5.9、Promise.prototype.then()
六、promise项目中使用
6.1、实现sleep函数
function sleep(ticks) { return Promise.resolve().then(() => { return ticks && sleep(ticks - 1); }); }
6.2、实现sleep函数
function sleep (seconds) { return new Promise((resolve) => { setTimeout(() => { resolve() }, seconds * 1000) }) }
6.3、实现同步请求
function myAsyncFunction(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.onload = () => resolve(xhr.responseText); xhr.onerror = () => reject(xhr.statusText); xhr.send(); }); };
6.4、nuxt3项目promise简单封装请求
nuxt3:我们开始吧-开发-配置-部署_snow@li的博客-CSDN博客
import { ElMessage } from 'element-plus' const fetch = (url: string, options?: any): Promise<any> => { const token = useCookie("token"); const headers = { // headers信息 'Authorization' : `Bearer ${token.value}` } const { public: { baseUrl } } = useRuntimeConfig() const reqUrl = baseUrl + url return new Promise((resolve, reject) => { useFetch(reqUrl, { ...options, headers }).then(({ data }: any) => { const value = data.value if (!data._rawValue) { // 这里处理错误回调 reject(value) }else if(data._rawValue.code !== '0'){ ElMessage({ message: data._rawValue.msg, type: 'error', }) } else { console.log('40data', data._rawValue) resolve(ref(data)) } }).catch((err: any) => { reject(err) }) }) } export default new class Http { get(url: string, params?: any): Promise<any> { return fetch(url, { method: 'get', params }) } post(url: string, params?: any): Promise<any> { return fetch(url, { method: 'post', params }) } put(url: string, body?: any): Promise<any> { return fetch(url, { method: 'put', body }) } delete(url: string, body?: any): Promise<any> { return fetch(url, { method: 'delete', body }) } }
6.5、Promise同步请求
let myPromise = new Promise(function(resolve, reject){ //当异步代码执行成功时,我们才会调用resolve(...) //当异步代码失败时就会调用reject(...) //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或其他内容 setTimeout(function(){ resolve("执行成功!") }, 250); }); myPromise.then(function(successMessage){ //successMessage的值是上面调用resolve(...)方法传入的值 console.log("Yay! " + successMessage); });
6.6、Promise链式调用
let c = new Promise((resolve, reject)=>{ resolve(100) }) .then((res)=>{ return new Promise((resolve)=>{ resolve(800 + res) }) // 这里的结果作为下一个then的res返回供使用 }) .then((res)=>{ console.log(res) }) // 900
七、相关内容
宏任务、微任务 、Generator 、Async / Await
八、欢迎交流指正,关注我,一起学习。