Promise(一)

Promise 介绍与基本使用

Promise 是什么?

  • 抽象表达

1)Promise 是一门新的技术(ES6规范)
2)Promise 是JS中进行异步编程的新解决方法
备注:旧方案是单纯使用回调函数

 异步编程
* fs 文件操作(nodejs的一个模块)
 require('fs').readFile('./index.html',(err,data) => {})
* 数据库操作
* AJAX
$.get('./list',(data) => {})
* 定时器
setTimeout( () => {},2000)
  • 具体表达

1)从语法上来说:Promise 是一个构造函数,所以可以 new 出一个Promise的实例
2)从功能上来说:Promise 对象用来封装一个异步操作并可以获取其成功/失败的结果值。
3)Promise是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。

  • 主要用于异步计算

  • 可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果

  • 可以在对象之间传递和操作promise,帮助我们处理队列

  • promise对象用来封装一个异步操作并可以获取其结果

为什么要用Promise

指定回调函数的方式更加灵活

  • 旧的:必须在启动异步任务前指定。
  • promise:启动异步任务 =》返回promise对象 =》给promise对象绑定回调函数(甚至可以在异步任务结束后指定/多个)

支持链式调用,可以解决回调地狱问题

什么是回调地狱?

回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调执行的条件。回调地狱就是在回调函数中再嵌套回调函数的一种现象。如代码所示:

setTimeout(()=>{
  console.log(1);
  setTimeout(()=>{
      console.log(2);
      setTimeout(()=>{
          console.log(3);
      },1000)
  },1000)
},1000)
回调地狱的缺点
  • 不便于阅读
  • 不便于异常处理
解决方案

promise +async/await

Promise 的基本使用

promise的案例

需求:
1、点击按钮,2s之后显示是否中奖(30%概率中奖)
2、若中奖,弹出 中奖了
3、若未中奖,弹出再接再厉

<button id="btn">抽奖</button>
<script> 
    function rand(m, n) {
        return Math.ceil(Math.random() * (n - m + 1)) + m - 1;
    }

    const btn = document.getElementById('btn');
    btn.addEventListener('click', () => {
        // 定时器
        // setTimeout(()=>{
        //     let n = rand(1,100)
        //     if(n <= 30){
        //         alert("中奖了")
        //     }else{
        //         alert('再接再厉')
        //     }
        // },2000)
        // Promise 形式实现
        //resolve 解决 函数类型的数据
        // reject 拒绝 函数类型的数据
        const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                let n = rand(1, 100)
                if (n <= 30) {
                    resolve(n); // 将 Promise 对象的状态设置为成功
                } else {
                    reject(n) // 将 Promise 对象的状态设置为失败
                }
            }, 2000)
        }); 
        p.then(
            n => { alert("中奖了,数字为"+n) },
            n => { alert("再接再厉,数字为"+n) }
        )
    }) 
</script>

fs读取文件

const fs = require('fs')

// 回调函数的形式
// fs.readFile('../static/demo.txt',(err,data) => {
//     if(err) throw err
//     console.log(data.toString())
// })

// Promise
const p = new Promise((resolve,reject) => {
    fs.readFile('../static/demo.txt',(err,data) => {
        if(err) reject(err) 
        resolve(data) 
    })
})

p.then(
    res =>{ console.log(res.toString()) },
    err => { console.log(err) }
)
/**
 * 封装一个函数 readFile 读取文件内容
 * 参数:path 文件路径
 * 返回:promise对象
 */

function readFile(path){
    return new Promise((resolve,reject) => {
        require('fs').readFile(path,(err,data) =>{
            if(err) reject(err)
            resolve(data)
        })
    })
}
readFile('../static/demo.txt').then(
    res => {console.log(res.toString())},
    err => {console.log(err)}
)
// util.promisify
// 引入util模块
const util = require('util');
// 引入fs模块
const fs = require('fs');
// 返回一个新的函数
let readFile = util.promisify(fs.readFile)

readFile('../static/demo.txt').then(res => {
    console.log(res.toString());
})

文件读取结果如下:
在这里插入图片描述

promise Ajax的使用

<button id="btn">发送AJAX请求</button> 
<script>

function ajaxFun(url){
    return new Promise((resolve,reject)=>{
        const xhr = new XMLHttpRequest(); 
        xhr.open('GET',url); 
        xhr.send(); 
        xhr.onreadystatechange = function(){
            if(xhr.readyState == '4'){
                if(xhr.status >= 200 && xhr.status < 300 ){  
                    resolve(xhr.response)
                }else{
                    reject(xhr.status) 
                }
            }
        }
    })
} 
document.getElementById('btn').addEventListener('click',function(){ 

    // const p = new Promise((resolve,reject) => {
    //     const xhr = new XMLHttpRequest(); 
    //     xhr.open('GET','http://127.0.0.1:8000/server'); 
    //     xhr.send(); 
    //     xhr.onreadystatechange = function(){
    //         if(xhr.readyState == '4'){
    //             if(xhr.status >= 200 && xhr.status < 300 ){  
    //                 resolve(xhr.response)
    //             }else{
    //                 reject(xhr.status) 
    //             }
    //         }
    //     }
    // })
    // p.then(
    //     res => { console.log(res) },
    //     err => { console.error(err); }
    // )

    ajaxFun('http://127.0.0.1:8000/server').then(
        res => { console.log(res) },
        err => { console.error(err); }
    ) 
})
</script>

Promise 的状态

在这里插入图片描述

  • 实例对象中的一个属性 【PromiseState】
  1. pending[待定]初始状态
  2. resolved/fulfilled[实现]操作成功
  3. rejected[被否决]操作失败
  • Promise的状态改变
  1. pending 变为resolved
  2. pending 变为rejected

说明:
只有这2种,且一个promise对象只能改变一次。promise状态一经改变,不会再变。
当promise状态发生改变,就会触发then()里的响应函数处理后续步骤;
无论成功还是失败,都会有1个结果数据

  • promise 实例对象的另一个属性 【PromiseResult】

保存着对象【成功/失败】的结果。

resolve reject函数可以修改该值。

Promise 的基本流程

在这里插入图片描述

Promise API

在这里插入图片描述

Promise构造函数:Promise(executor){}

  • executor函数:执行器 (resolve,rejecte) => {}
  • resolve函数:内部定义成功时我们调用的函数 res => {}
  • reject函数:内部定义失败时我们调用的函数 err => {}
  • 说明:executor 会在Promise 内部立即同步调用,异步操作在执行器中执行。
/**
 * (resolve,reject) => {} 被称为执行器函数 同步调用 
 */
const p = new Promise((resolve,reject) => {
    console.log(111); // 同步调用
})
console.log(222);

执行结果如下:
在这里插入图片描述

Promise.prototype.then方法:(onResolved,onRejected) => {}

  • onResolved函数:成功的回调函数 res => {}
  • onRejected函数:失败的回调函数 err => {}
  • 说明:指定用于得到成功 res 的 的成功回调和用户得到失败 err 的失败回调,返回一个新的promise对象

Promise.prototype.catch方法:(onRejected) => {}

  • onRejected 函数:失败的回调函数 err => {}
  • 在Promise状态为rejected时执行,then方法捕捉到Promise的状态为rejected,就执行catch方法里面的操作.
const p1 = new Promise((resolve,reject) => {
     reject('error')
})
p1.catch(err =>{ console.log(err); })

Promise.resolve方法:(res) => {}

  • res:成功的数据或promise对象
  • 说明:返回一个成功/失败的promise对象
// 如果传入的参数为 非Promise类型的对象,则返回的结果为成功的promise对象
// 如果传入的参数为promise对象,则参数的结果决定了 resolve 的结果。
let p = Promise.resolve(520); 
let p1 = Promise.resolve(new Promise((resolve,reject) => {
    resolve('OK')
}))
let p2 = Promise.resolve(new Promise((resolve,reject) => {
    reject('Error')
}))
p2.catch(err => {
    console.log(err)
})
console.log("p",p);
console.log("p1",p1);
console.log("p2",p2);

在这里插入图片描述

Promise.reject方法:(err) => {}

  • err:失败的原因
  • 说明:返回一个失败的Promise对象
  • reject方法返回的是错误信息,将Promise的状态置为rejected
 // 不管你传入什么 都是失败,失败的值是你传入的值
 let p = Promise.reject(520); 
 p.catch(err => {
     console.log("p - err",err)
 })
 let p1 = Promise.reject(new Promise((resolve,reject) => {
     resolve('OK')
 }))
 p1.catch(err => {
     console.log("p1 - err",err)
 }) 
 console.log("p",p);
 console.log("p1",p1);

在这里插入图片描述

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

  • promises:包含n个promise的数组
  • 说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败了就直接失败。
 let p = new Promise((resolve,reject) => {
  resolve("p 成功")
 })
 let p1 = new Promise((resolve,reject) => {
     resolve("p1 成功")
 })
 let p2 = new Promise((resolve,reject) => {
     resolve("p2 成功")
 })
 let result = Promise.all([p,p1,p2]);
 console.log(result);

在这里插入图片描述

let p = new Promise((resolve,reject) => {
 	resolve("p 成功")
})
let p1 = new Promise((resolve,reject) => { 
    reject("p1 失败")
})
p1.catch((err)=>{
    console.log(err);
})
let p2 = new Promise((resolve,reject) => {
    resolve("p2 成功")
})
let result = Promise.all([p,p1,p2]);
console.log(result);

在这里插入图片描述

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

  • promises:包含n个promise的数组
  • 说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态。
let p = new Promise((resolve,reject) => { 
    setTimeout( ()=>{
        resolve("p 成功")
    },1000)
})
let p1 = new Promise((resolve,reject) => {
    resolve("p1 成功")
}) 
let p2 = new Promise((resolve,reject) => {
    resolve("p2 成功")
})
let result = Promise.race([p,p1,p2]);
console.log(result);

第一个完成的promise是p1在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值