1、resolve方法封装
具体代码:
Promise.resolve = function (value) {
//返回promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(value => {
resolve(value)
}, (reason) => {
reject(reason)
})
}else {
resolve(value)
}
})
}
2、reject方法封装
//添加promise的reject静态方法
Promise.reject=function(reason){
//返回promise对象
return new Promise((resolve,reject)=>{
reject(reason)
})
}
以上两例的全部代码
//相当于重写promise
function Promise(excutor){
//添加属性
this.PromiseState='pending'
this.PromiseResult=''
//在这里保存一个callback属性用来存放onResolved和onRejected方法
this.callbacks=[]
const that=this
//同步调用执行器函数
function resolve (data) {
if (that.PromiseState!=='pending'){
return
}
//修改对象的状态。promiseState
that.PromiseState='fulfilled'
//设置对象结果值promiseReuslt
that.PromiseResult=data
//异步状态下执行成功的回调函数(这里有点回归的意思)
that.callbacks.forEach(item=>{
item.onResolved(data)
})
}
function reject (data) {
if (that.PromiseState!=='pending'){
return
}
that.PromiseState='rejected'
that.PromiseResult=data
//异步状态下执行失败的回调函数
that.callbacks.forEach(item=>{
item.onRejected(data)
})
}
//这里要执行这个执行器函数
try{
excutor(resolve,reject)
}
catch (e) {
reject(e)//
}
}
Promise.prototype.then=function(onResolved,onRejected){
const that=this
//做异常穿透要判断回调参数
if (typeof onRejected !=='function'){
onRejected=(reason)=>{
throw reason
}
}
if (typeof onResolved !=='function'){
onResolved=(value)=>{
return value
}
}
return new Promise((resolve,reject)=>{
//封装函数
function callback (type) {
//获取回调函数的执行结果
let result=type(that.PromiseResult)
if (result instanceof Promise){
//如果是Promise类型的对象
result.then(value=>{
resolve(value)
},reason => {
reject(reason)
})
}else{
//结果对象设为成功
resolve(result)
}
}
try{
//调用回到函数,需要做对this.PromiseState做条件判断
if (this.PromiseState=='fulfilled'){
callback(onResolved)
}
if (this.PromiseState=='rejected'){
callback(onRejected)
}
//异步状态下这里先执行
if (this.PromiseState=='pending'){
//把两个函数存储到callback属性上去
//考虑到多次使用then,因此存储以push的方式push到数组中去
this.callbacks.push({
onResolved:function(){
try{
callback(onResolved)
}catch (e) {
reject(e)
}
},
onRejected:function () {
try{
callback(onRejected)
}catch (e) {
reject(e)
}
}
})
}
}
catch (e) {
reject(e)
}
})
}
//添加promise的catch方法
Promise.prototype.catch=function (onRejected) {
return this.then(undefined,onRejected)
}
//添加promise的resolve静态方法
Promise.resolve=function (value) {
//返回promise对象
return new Promise((resolve,reject)=>{
if (value instanceof Promise){
value.then(value => {
resolve(value)
},(reason)=>{
reject(reason)
})
}
})
}
//添加promise的reject静态方法
Promise.reject=function(reason){
//返回promise对象
return new Promise((resolve,reject)=>{
reject(reason)
})
}
3、all方法封装
- all方法所有promise成功才能成功,所以需要遍历参数数组
- 在每一个参数数组元素(promise)执行then的结果,执行计数器加一,并将结果添加到结果数组中
- 到了计数器和参数数组长度一致的时候,则返回那个结果数组
//添加promise的all静态方法
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
//设置一个计数变量
let count = 0
//设置接收返回的promise对象数组
let promisesArry = []
for (let i = 0; i < promises.length; i++) {
//遍历每一个promises参数中的promise对象
promises[i].then((value) => {
//得知对象成功则计数器加一
count++
//把处理结果值依次放到返回的promise对象数组中
promisesArry[i] = value
//如果每次都可以返回则循环计数器将最终等于参数数组的长度
if (count === promises.length) {
//最后一次性resolve完整个promise数组
resolve(promisesArry)
}
}, (reason) => {
//只要一旦计入到一个reject,整体就返回reason了
reject(reason)
})
}
})
}
脚本中执行
<script>
$('#send_ajax').click(function(){
let promise1=new Promise((resolve,reject)=>{
//resolve(ok)
setTimeout(()=>{
resolve('ok')
},1000)
})
// let promise2=new Promise.resolve('成功')
// let promise3=new Promise.resolve('success')
let promise2=new Promise((resolve,reject)=>{
resolve('成功')
})
let promise3=new Promise((resolve,reject)=>{
resolve('succes')
})
let result=Promise.all([promise1,promise2,promise3])
console.log(result)
})
</script>
结果:
非异步状态下:
异步状态下:
4、race方法封装
- 先返回成功就全部成功,先返回失败就全部失败
- 由于异步处理,先执行同步代码,所以race的结果肯定是看第一条同步代码的返回值
- 如果是同步处理,则看第一条同步代码的返回值,所以,异步处理结果一般来说不影响race的执行结果
//添加promise的race静态方法
Promise.race=function (promises) {
return new Promise((resolve,reject)=>{
for (let i=0; i<promises.length;i++){
promises[i].then((value)=>{
resolve(value)
},(reason)=>{
reject(reason)
})
}
})
}
执行代码
<script>
$('#send_ajax').click(function(){
let promise1=new Promise((resolve,reject)=>{
// reject('fail')
setTimeout(()=>{
reject('fail')
},1000)
})
let promise2=new Promise.resolve('成功')
let promise3=new Promise((resolve,reject)=>{
resolve('succes')
})
let result=Promise.race([promise1,promise2,promise3])
console.log(result)
})
</script>
结果:
异步代码情形下
同步代码情形下
5、then方法回调的异步执行
then方法修改这里
//调用回到函数,需要做对this.PromiseState做条件判断
if (this.PromiseState == 'fulfilled') {
//异步执行加定时器
setTimeout(()=>{
callback(onResolved)
})
}
if (this.PromiseState == 'rejected') {
setTimeout(()=>{
callback(onRejected)
})
}
主要是在then方法里修改,这里是then方法
Promise.prototype.then = function (onResolved, onRejected) {
const that = this
//做异常穿透要判断回调参数
if (typeof onRejected !== 'function') {
onRejected = (reason) => {
throw reason
}
}
if (typeof onResolved !== 'function') {
onResolved = (value) => {
return value
}
}
return new Promise((resolve, reject) => {
//封装函数
function callback (type) {
//获取回调函数的执行结果
let result = type(that.PromiseResult)
if (result instanceof Promise) {
//如果是Promise类型的对象
result.then(value => {
resolve(value)
}, reason => {
reject(reason)
})
} else {
//结果对象设为成功
resolve(result)
}
}
try {
//调用回到函数,需要做对this.PromiseState做条件判断
if (this.PromiseState == 'fulfilled') {
setTimeout(()=>{
callback(onResolved)
})
}
if (this.PromiseState == 'rejected') {
callback(onRejected)
}
//异步状态下这里先执行
if (this.PromiseState == 'pending') {
//把两个函数存储到callback属性上去
//考虑到多次使用then,因此存储以push的方式push到数组中去
this.callbacks.push({
onResolved: function () {
try {
callback(onResolved)
} catch (e) {
reject(e)
}
},
onRejected: function () {
try {
callback(onRejected)
} catch (e) {
reject(e)
}
}
})
}
} catch (e) {
reject(e)
}
})
}
此外在resolve和reject里面也要调用一下setimeout方法
//同步调用执行器函数
function resolve (data) {
if (that.PromiseState !== 'pending') {
return
}
//修改对象的状态。promiseState
that.PromiseState = 'fulfilled'
//设置对象结果值promiseReuslt
that.PromiseResult = data
setTimeout(()=>{
//异步状态下执行成功的回调函数(这里有点回归的意思)
that.callbacks.forEach(item => {
item.onResolved(data)
})
})
}
function reject (data) {
if (that.PromiseState !== 'pending') {
return
}
that.PromiseState = 'rejected'
that.PromiseResult = data
setTimeout(()=>{
//异步状态下执行失败的回调函数
that.callbacks.forEach(item => {
item.onRejected(data)
})
})
}
执行代码:
<script>
$('#send_ajax').click(function(){
let promise1=new Promise((resolve,reject)=>{
resolve('ok')
console.log(111)
})
promise1.then(value=>{
//console.log(value)
console.log(2222)
})
console.log(333)
})
</script>
结果
最终的自定义Promise包为:
//相当于重写promise
function Promise (excutor) {
//添加属性
this.PromiseState = 'pending'
this.PromiseResult = ''
//在这里保存一个callback属性用来存放onResolved和onRejected方法
this.callbacks = []
const that = this
//同步调用执行器函数
function resolve (data) {
if (that.PromiseState !== 'pending') {
return
}
//修改对象的状态。promiseState
that.PromiseState = 'fulfilled'
//设置对象结果值promiseReuslt
that.PromiseResult = data
setTimeout(()=>{
//异步状态下执行成功的回调函数(这里有点回归的意思)
that.callbacks.forEach(item => {
item.onResolved(data)
})
})
}
function reject (data) {
if (that.PromiseState !== 'pending') {
return
}
that.PromiseState = 'rejected'
that.PromiseResult = data
setTimeout(()=>{
//异步状态下执行失败的回调函数
that.callbacks.forEach(item => {
item.onRejected(data)
})
})
}
//这里要执行这个执行器函数
try {
excutor(resolve, reject)
} catch (e) {
reject(e)//
}
}
Promise.prototype.then = function (onResolved, onRejected) {
const that = this
//做异常穿透要判断回调参数
if (typeof onRejected !== 'function') {
onRejected = (reason) => {
throw reason
}
}
if (typeof onResolved !== 'function') {
onResolved = (value) => {
return value
}
}
return new Promise((resolve, reject) => {
//封装函数
function callback (type) {
//获取回调函数的执行结果
let result = type(that.PromiseResult)
if (result instanceof Promise) {
//如果是Promise类型的对象
result.then(value => {
resolve(value)
}, reason => {
reject(reason)
})
} else {
//结果对象设为成功
resolve(result)
}
}
try {
//调用回到函数,需要做对this.PromiseState做条件判断
if (this.PromiseState == 'fulfilled') {
//异步执行加定时器
setTimeout(()=>{
callback(onResolved)
})
}
if (this.PromiseState == 'rejected') {
setTimeout(()=>{
callback(onRejected)
})
}
//异步状态下这里先执行
if (this.PromiseState == 'pending') {
//把两个函数存储到callback属性上去
//考虑到多次使用then,因此存储以push的方式push到数组中去
this.callbacks.push({
onResolved: function () {
try {
callback(onResolved)
} catch (e) {
reject(e)
}
},
onRejected: function () {
try {
callback(onRejected)
} catch (e) {
reject(e)
}
}
})
}
} catch (e) {
reject(e)
}
})
}
//添加promise的catch方法
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
//添加promise的resolve静态方法
Promise.resolve = function (value) {
//返回promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(value => {
resolve(value)
}, (reason) => {
reject(reason)
})
}else {
resolve(value)
}
})
}
//添加promise的reject静态方法
Promise.reject = function (reason) {
//返回promise对象
return new Promise((resolve, reject) => {
reject(reason)
})
}
//添加promise的all静态方法
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
//设置一个计数变量
let count = 0
//设置接收返回的promise对象数组
let promisesArry = []
for (let i = 0; i < promises.length; i++) {
//遍历每一个promises参数中的promise对象
promises[i].then((value) => {
//得知对象成功则计数器加一
count++
//把处理结果值依次放到返回的promise对象数组中
promisesArry[i] = value
//如果每次都可以返回则循环计数器将最终等于参数数组的长度
if (count === promises.length) {
//最后一次性resolve完整个promise数组
resolve(promisesArry)
}
}, (reason) => {
//只要一旦计入到一个reject,整体就返回reason了
reject(reason)
})
}
})
}
//添加promise的race静态方法
Promise.race=function (promises) {
return new Promise((resolve,reject)=>{
for (let i=0; i<promises.length;i++){
promises[i].then((value)=>{
resolve(value)
},(reason)=>{
reject(reason)
})
}
})
}
6、async函数
- 函数的返回值为promise对象
- promise对象的结果由async函数的返回值决定
async function main () {
//如果返回值是一个非promise对象
//return 333
//如果返回值是一个promise对象,则函数返回的对象就返回的promise对象的返回值
return new Promise((resolve,reject)=>{
//resolve('成功')
reject('失败')
})
}
let result=main()
console.log(result)
7、await表达式
- await右侧的表达式一般为promise对象,但也可以是其他的值
- 如果表达式是promise对象,await返回的是promise成功的值
- 如果表达式是其他值,则直接将此值作为await的返回值
- await必须写在async函数中,但async函数中可以没有await
- 如果await的promise失败了,就会抛出异常,需要通过try…catch捕获处理
<script>
$('#send_ajax').click(function(){
async function main () {
let p=new Promise((resolve ,reject)=>{
reject('fail')
})
//1、右侧为promise的情况
//return await p
//2、右侧为其他数据的情形
//return await 111
//3、右侧promise为失败的状态
try{
let result=await p
return result
}catch (e) {
return e
}
}
let result=main()
console.log(result)
})
</script>
8、async结合await
传统写法(有回调地狱):
const fs =require('fs')
let str=fs.readFile('../public/async1.txt',(err1,data1)=>{
if (err1) throw err1
fs.readFile('../public/async2.txt',(err2,data2)=>{
if (err2) throw err2
fs.readFile('../public/async3.txt',(err3,data3)=>{
if (err3) throw err3
console.log(data1+data2+data3)
})
})
})
aysnc写法:
const fs =require('fs')
//导入util模块
const util=require('util')
//利用util的promisify将fs.readFile转化为
const mineReadFile=util.promisify(fs.readFile)
async function mytest(){
let data1=await mineReadFile('../public/async1.txt')
let data2=await mineReadFile('../public/async2.txt')
let data3=await mineReadFile('../public/async3.txt')
console.log(data1+data2+data3)
}
mytest()
9、async结合await发送ajax请求
<script>
//未来这个函数可以使用axios进行封装
function sendAjax(url) {
const promise = new Promise((resolve, reject) => {
$.ajax({
url: url,
type: 'GET',
success (msg) {
if (msg.status) {
resolve(msg)
} else {
reject('请求失败')
}
}
})
})
promise.then((value) => {
console.log(value.data)
}, (reason) => {
console.log(resolve)
})
}
$('#send_ajax').click(async function(){
let url='http://localhost:3000/test'
const result=await sendAjax(url)
console.log(result)
})
</script>