Promise 对象

目录

Promise Ajax 请求函数封装

Promise 介绍

创建 Promise 实例

Promise 内部状态

Promise 原型链方法

Promise 静态方法


Promise Ajax 请求函数封装

// 封装 ajax 请求函数
function ajax(url, successCallback, failCallback){
	// 创建 XMLHttpRequest 对象
	let xmlhttp
	if(window.XMLHttpRequest){
		xmlhttp = new XMLHttpRequest()
	} else {
		xmlhttp = new ActiveXObject('Microsoft.XMLHTTP')
	}

	// 发送请求
	xmlhttp.open('GET', url, true)
	xmlhttp.send()

	// 服务端响应
	xmlhttp.onreadystatechange = function(){
		if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
			const obj = JSON.parse(xmlhttp.responseText)
			successCallback(obj)
		} else if (xmlhttp.readyState === 4 && xmlhttp.status === 404){
            /** 此处必须写 else if 不能只写 else,否则接口请求的时候只会进入 catch 状态 */
			console.log('xmlhttp', xmlhttp)
			failCallback(xmlhttp.statusText)
		}
	}
}

// 封装 Promise 函数
function getPromise(url){
	return new Promise((resolve, reject) => {
		ajax(url, res => {
			resolve(res)
		}, err => {
			reject(err)
		})
	})
}

const url1 = 'http://jsonplaceholder.typicode.com/users'
const url2 = 'http://jsonplaceholder.typicode.com/todos'
const url3 = 'http://jsonplaceholder.typicode.com/photos1'

// 调用 Promise 函数
getPromise(url1).then(res => {
	console.log(res)
	return getPromise(url2)
}).then(res => {
	console.log(res)
	return getPromise(url3)
}).then(res => {
	console.log(res)
}).catch(err => { // 统一做错误处理
	console.log(err)
}).finally(() => {
    console.log('无论成功或失败都会执行的方法')
})

Promise 介绍

  • Promise 为了解决“回调地狱”问题,它可以将异步操作处理变得很优雅
  • 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入
  • Promise 可以支持多个并发请求,获取并发请求中的数据
  • Promise 可以解决异步的问题,本身不能说 Promise 是异步的;Promise 是一个构造函数

创建 Promise 实例

const promise = new Promise(function(resolve, reject) {
    // ... some code

    if ( /* 异步操作成功 */ ) {
        resolve(value)
    } else {
        reject(error)
    }
})
  • Promise 是一个构造函数接收一个函数作为参数,该函数两个参数分别是 resolve 和 reject
  • resolve 和 reject 是两个函数,由 JS 引擎提供,不用自己部署
  • 处理结果正常调用 resolve 方法(处理结果值),将 Promise 对象状态从“未完成”变为“成功”(即从 pending 变为 fulfilled),resolve 在异步操作成功时调用,并将异步操作的结果,作为参数传递出去
  • 处理结果错误,调用 reject 方法(Error对象),将 Promise 对象状态从“未完成”变为“失败”(即从 pending 变为 rejected),reject 在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去
     

Promise 内部状态

  • Promise 内部是有状态的(pending、fulfilled、rejected),Promise 对象根据状态来确定执行哪个方法
  • Promise 实例化时状态默认 pending;当异步操作完成,状态会被修改为 fulfilled,如果异步操作遇到异常,状态会被修改为 rejected
  • 可以通过下图来看状态走向

Promise 原型链方法

  • Promise.prototype.then() 方法请求成功时执行的回调函数
  • Promise.prototype.catch() 方法请求失败时执行的回调函数
  • Promise.prototype.finally() 方法不管最后状态如何都会执行的回调函数,在执行 then() 和 catch() 后,都会执行 finally 指定的回调函数;ES9 新增的方法
new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('success')
        // reject('fail')
    }, 1000)
}).then(res => {
    console.log(res)
}).catch(err => {
    console.log(err)
}).finally(() => {
    console.log('finally')
})

使用场景:loading 关闭

  • 需要每次发送请求,都会有 loading 提示
  • 请求发送完毕需要关闭 loading 提示框,不然界面就无法被点击

Promise 静态方法 6 个

1)Promise.resolve()

  • 静态方法 Promise.resolve(value) 是 new Promise() 方法的快捷方式
  • Promise.resolve(42) 是以下代码的语法糖
new Promise(function(resolve) {
    resolve(42)
})
  • Promise.resolve(value) 返回值是一个 Promise 对象,可以像下面代码对其返回值进行 .then 调用
Promise.resolve(42).then(function(value) {
    console.log(value)
})

2)Promise.reject()

  • Promise.reject(error) 和 Promise.resolve(value) 是类似的静态方法,是 new Promise() 方法的快捷方式
  • Promise.reject("出错了") 是下面代码的语法糖形式
new Promise(function(resolve, reject) {
    reject('出错了')
})

3)Promise.all(promiseArray)

  • Promise.all() 具有并发执行异步任务的能力
  • Promise.all() 最大问题如果其中某个任务出现异常(reject),所有任务都会挂掉,Promise 直接进入 rejected 状态,直接返回 reject 返回的值
  • Promise.all() 接收一个数组作参数,数组里面的每一项元素都是一个 Promise 实例对象
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = Promise.resolve(3)
Promise.all([p1, p2, p3]).then(function(results) {
    console.log(results)
})
  • 只有 p1、p2、p3 的状态都变成 fulfilled,p 的状态才会变成 fulfilled,此时 p1、p2、p3 的返回值组成一个数组,传递给 p 的回调函数
const p1 = Promise.resolve(1)
const p2 = Promise.reject(2)
const p3 = Promise.resolve(3)
Promise.all([p1, p2, p3]).then(function(results) {
    console.log(results)
})
  • 只要 p1、p2、p3 之中有一个被 rejected,p 的状态就变成 rejected,此时第一个被 reject 的实例返回值,会传递给 p 的回调函数

4)Promise.allSettled()

  • 具有并发执行异步任务的能力,无论一个任务成功或失败,都会返回对应的的状态
  • 可以使用此方法过滤出成功状态的数据
Promise.allSettled([
	Promise.reject({code: 500, msg: '服务器异常'}),
	Promise.resolve({code: 200, date: [1, 2, 3]}),
	Promise.resolve({code: 200, date: [4, 5, 6]}),
]).then(res => {
	console.log(res)
	console.log('成功')
	// 过滤出成功状态返回的数据
	const data = res.filter(item => item.status === 'fulfilled' )
	console.log('过滤出成功状态返回的数据', data)
}).catch(err => {
	console.log(err)
	console.log('失败')
})

promise.all() 和 promise.allSettled() 区别

  • 相同参数对应处理方式不同
  • Promise.allSettled() 不管参数中 Promise 状态是 fulfilled 还是 rejected,都会等参数中的实例都返回结果,包装实例才会结束
  • Promise.all() 只有在接收所有 Promise 实例全部都是 fulfilled 才会走
  • Promise.all([p1,p2,p3]).then()方法,只要其中一个 Promise 实例是 rejected,直接走 catch 方法,并且 catch 只会返回第一个变成 rejected 的 Promise 错误

5)Promise.race()

  • 一旦迭代器中的某个 Promise 解决或拒绝,返回的 Promise 就会解决或拒绝
  • 返回值:一个待定的 Promise 只要给定的迭代中的一个 promise 解决或拒绝,就采用第一个 Promise 的值作为它的值,从而异步地解析或拒绝;如果传的迭代是空的,则返回的 Promise 将永远等待
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = Promise.resolve(3)
Promise.race([p1, p2, p3]).then(function(value) {
  console.log(value) // 1
})

6)Promise.any()

  • 类似 Promise.race()
  • Promise.any() 接收一个 Promise 可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 Promise 返回的值
  • 如果可迭代对象中所有的 Promise 都失败/拒绝,就返回一个失败的 Promise 和AggregateError 类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起。本质上,这个方法和 Promise.all() 是相反的
  • Promise.any() 方法依然是实验性的,尚未被所有的浏览器完全支持。它当前处于草案
  • Promise.any() 中只要有一项 Promise 状态是 fulfilled 状态就会在 .then() 中执行,返回那个已经成功的 Promise
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = Promise.resolve(3)
Promise.any([p1, p2, p3]).then(res => {
	console.log(res)
}).catch(err => {
	console.log(err) // 1
})
  • Promise.any() 中当所有数组项都是 rejected 状态时,就会在 .catch() 中执行
const p1 = Promise.reject(1)
const p2 = Promise.reject(2)
const p3 = Promise.reject(3)
Promise.any([p1, p2, p3]).then(res => {
	console.log(res)
}).catch(err => {
	console.log(err) // AggregateError: All promises were rejected
})

ES8:async await 更加优雅的异步编程解决方案_taoqidejingling的博客-CSDN博客async 和 await 是一种更加优雅的异步编程解决方案,await 后面返回的是一个 Promise 对象;await 后面跟的代码会变成同步任务;案例使用 async await 发送接口请求https://blog.csdn.net/taoqidejingling/article/details/123097323 

异步操作前置知识_taoqidejingling的博客-CSDN博客JS 是单线程语言;同步任务和异步任务;Ajax 请求;Callback Hell 回调地狱(回调深渊)https://blog.csdn.net/taoqidejingling/article/details/122984154 

ECMAScript2015~2020语法全解析http://es.xiecheng.live/es6/promise.html

Promise.all、Promise.race、Promise.allSettled所有静态方法总结 - Mjser - 博客园promise的静态方法 前言 前一篇我们已经介绍了关于自己实现promise的文章前端面试题之手写promise,本篇我们主要介绍的是promise的静态方法all、race、allSettled、https://www.cnblogs.com/crim/p/15481712.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值