IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Promise 对象:Promise Ajax 请求函数封装 -> 正文阅读

[JavaScript知识库]Promise 对象:Promise Ajax 请求函数封装

目录

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)
})

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 静态方法

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
})

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

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-22 20:29:58  更:2022-02-22 20:30:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:32:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码