Promise

promise最大的好处解决地狱回调问题

Promise是es6引入的进行异步编程的新解决方案

Promise是一个构造函数,可以进行对象的实例化

Promise可以用来封装一个异步操作,并且可以获取其成功或者失败的结果值

异步编程

fs文件操作(fs是nodejs下的一个模块,可以对计算机磁盘进行读写操作)

以前:(err,data)=>{}使用的是回调

require('fs').readfile('./index.html',(err,data)=>{})

数据库操作( mangdb ,mysql等数据库操作)

AJAX(网络请求)

data=>{}为一个回调函数

$.get('/server',(data)=>{})

定时器(setTimeout)

setTimeOut(()=>{},2000)

使用Promise的优势

1.支持链式调用,可以解决回调地域问题。

回调地狱:一个回调函数套着另外一个异步任务。缺点:1.不便于阅读2.不便于异常处理

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

之前必须在执行异步任务之前就得把回调函数准备好

现在有了promise之后:启动异步任务=>返回promise对象=>给promise绑定回调函数(甚至在异步任务之后指定多个回调函数处理成功或者失败的结果)

Promise使用 -fs模块

//fs可以对计算机硬盘进行读写操作
//要求读取resouse文件下面的content.txt
//
//回调函数形式
// //引进fs
const fs = require('fs');
// fs.readFile('./resource/content.txt',(err, data)=>{
//   //如果出错,则抛出错误
//   if(err) throw err;
// //  没错,输出文件内容
//   console.log(data.toString())
// //  终端运行   node Promise练习-fs模块.js
// })

//Promise形式
//创建一个Promise对象
let p =new Promise((resole,reject)=>{
  fs.readFile('./resource/content.txt1',(err,data)=>{
    //如果出错,抛出
    if(err) reject(err);
  //  如果成功
    resole(data);
  })
});
//调用then方法
p.then(value=>{
  console.log(value.toString())
},reason => {
  console.log(reason)
})


 reason就是出错

 Promise练习AJAX

把异步代码放进Promise中,成功调用resolve,失败调用reject  ,并把成功失败结果传进去,

在then方法中调用成功和失败的回调,对结果进行处理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>Promise封装AJAX</h2>
<button id="btn">点击发送AJAX</button>
<script>
    //    接口地址https://api.apiopen.top/getJoke
    //获取元素对象
    // const btn = document.querySelector('btn');
    //绑定事件
    btn.addEventListener('click', function () {
//     AJAX四部操作
//         创建Promise
        const p = new Promise((resolve, reject) => {
            //     1.创建对象
            const xhr = new XMLHttpRequest();
//    2.初始化
            xhr.open('GET', 'https://api.apiopen.top/getJoke')
//    3.发送
            xhr.send();
//    4.处理响应结果
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    //    判断响应状态码2XX
                    if (xhr.status >= 200 && xhr.status < 300) {
                        //    输出响应体response
                        // console.log(xhr.response)
                        resolve(xhr.response)
                    } else {
                        // console.log(xhr.status)
                        reject(xhr.status)
                    }
                }

            }
        });
        p.then(value=>{
            console.log(value)
        },reason=>{
            console.log(reason)
        })

    })
</script>
</body>
</html>

 Promise封装AJAX请求

在别的页面可以使用,在别的页面引入sendAJAX,放置不同的url参数即可

xhr.responseType='json'AJAX设置返回类型
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
//    封装一个sendAJAX请求,发送GET AJAX    参数:URL   返回结果:Promise对象
function sendAJAX(url){
    return new Promise((resolve,reject)=>{
        //1.创建XMLHTTPRequest对象
        const xhr = new XMLHttpRequest()
        xhr.responseType='json';
        //2.初始化模板
        xhr.open('GET',url)
        //3.发送
        xhr.send();
        //处理结果onreadystatechange
        xhr.onreadystatechange=function(){
            if(xhr.readyState===4){
            //    判断成功
                if(xhr.status>=200&&xhr.status<300){
                    resolve(xhr.response)
                }else{
                    reject(xhr.status)
                }
            }
        }
    })
}
sendAJAX('https://api.apiopen.top/getJoke').then(
    value => {
        console.log(value)
    },
    reason => {
        console.log(reason)
    }
)
</script>
</body>
</html>

Promise封装一个读取函数mineReadFile

//封装一个mineReadFile  参数:path路径   返回:promise对象
function mineReadFile(path){
//  返回结果为promise对象
  return new Promise((resolve,reject)=>{
  //  功能为读取文件
  //  readFile第一个参数给path  第二个参数为回调
    require('fs').readFile(path,(err,data)=>{
      if(err)reject(err)
      resolve(data)
    })
  })
}
mineReadFile('./resource/content.txt')
  .then(value=>{
//  输出文件内容
    console.log(value.toString())
},reason =>{
  console.log(reason)
})

node.js中内置方法promisify 

这个方法是 属于util模块的  util.promisify

官方文档:传入一个常见的错误优先的回调风格的函数。

其实是错误优先的回调。在fs中异步的API基本上的回调函数都是err 是第一个参数

会返回一个peomise版本

//util.promisity方法
//引入util模块
const util =require('util')
//引入fs
const fs =require('fs')
let mineReadFile = util.promisify(fs.readFile)
mineReadFile('./resource/content.txt').then(value=>{
  console.log(value.toString())
},reason=>{})

 Promise的状态改变PromiseState

状态是promise对象中的一个属性,是promise实例对象当中的一个属性 PromiseState

是内置属性,不能进行操作

 有三种值:

pending  未决定的

resolved/ fullfilled  成功

rejected  失败

两种可能的变化,只能改变一次

pending变为resolved

pending变为rejected

Promise对象的值PromiseResult

PromiseResult是Promise实例对象的另一个属性

保存着   异步任务    对象成功或者失败的结果

resolve和reject可以修改PromiseResult的值

如何使用Promise

Promise相关的API

Peomise的构造函数:Promise(excutor){}

1.excutor函数:执行器(resolve,reject)=>{ }

2.resolve函数:内部定义成功时调用的函数value=>{}

3.reject函数:内部定义失败时调用的函数reason=>{ }

4.excutor的参数,也就是(resolve,reject)={} 函数的参数是同步调用的,异步操作在执行器中执行

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

then方法用来指定回调的,传递两个参数,这些参数都是函数类型的参数

1.onResolved:成功的回调函数value=>{}

2.onRjected:失败的回调函数reason=>{}

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

1.onReject函数:失败时的回调(reason)=>{}

Promise.resolve 方法:value=>{}

1.value:返回一个成功或者失败的promise对象

属于Promise对象,不是实例对象

如果传入参数为非Promise类型的对象,则返回结果为成功promise对象

如果传入的参数为Promise类型的对象,则参数的结果决定resolve的结果

 Promise.reject方法:reject=>{}

属于promise这个对象,不属于实例对象

1.reason失败的原因

说明:返回一个失败的peomise对象

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

1.promises:包含n个promise数组

说明:返回一个新的peomise,只有所有的peomise成功才成功,只要有一个失败就直接失败

 成功:

 

 失败:结果为失败的那个值

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

1.promises:包含n个promise对象的数组

说明:返回一个promise,第一个完成peomise的结果状态就是最终的结果

Promise中的几个关键问题

1.如何改变promise的状态

1.调用resolve函数,状态由pending变为resolved/fullfilled

2.调用reject函数,状态由pending变为rejected

3.抛出错误 throw

2.一个promise指定多个成功/失败回调函数,都会调用吗

意思就是then里面的回调,会执行吗?

当promise状态改变之后都会调用,没有调用resolve('ok')的时候都不会调用

 3.改变promise状态和指定回调函数谁先谁后

改变状态:resolve,reject,throw

指定回调函数:then,catch

该题可变为:resolve改变状态先执行还是then回调先执行

都有可能

1.改变状态先执行,Promise实列对象是一个同步函数时

 2.then指定回调先执行,Promise实例对象中是一个异步函数

异步任务居多

 如何先改变状态

1. 在执行器中直接调用resolve/reject

2.异步:给then回调加更长的异步

什么时候能拿到数据?

指的是回调函数then到底什么时候执行

1.先改变状态,立即调用resolve,这时then在调用就会执行回调函数,处理成功或者失败的结果

2.如果是先指定的then回调,后改变状态,这时时改变状态以后,去调用成功或者失败的结果

 promise.then()返回的新的promise的结果状态由什么决定

就是result的状态由什么决定

1.答案:是由then指定的回调函数执行结果决定

2.如果抛出异常,新promise变为rejected, reason为抛出的异常
如果返回的是非promise的任意值,新 promise变为resolved, value为返回的值

如果返回的是另一个新promise,此promise的结果就会成为新promise的结果

Promise如何串联多个操作任务

promise 的 then()返回一个新的promise对象,可以开成then()的链式调用

通过then的链式调用串连多个同步/异步任务

 

 第三个console.log的值是由上一个then的返回结果promise决定的,由指定回调函数的返回值决定的,没写返回值就是undefined ,undefined不是一个promise类型的对象,所以返回一个成功的undefined

Promise异常穿透

1.当使用peomise的then方法链式调用时,可以在最后指定失败的回调

用then需要传两个参数,用catch传一个就行

 中断Promise链

有且只有一种方式:返回一种pending状态的Promise对象

return new Promise(()=>) 返回为pending 状态没有改变  其他就不会执行

 

手写Promise----实现之前的API

报错:

 

p.then会报错     在promise.js中的Promise构造函数上 即显示原型对象上  没有then方法

Promise原型上没有 那么 p实例对象的隐式原型链上就没有then方法

为了能调用then方法,需要添加then方法

resolve函数执行:

1.Promise对应的状态会发生改变由pending变为resolved/fullfilled   状态是实例对象上的一个属性PromiseState ,PromiseState是属于实例对象的 

2.设置Promise对象的结果  PromiseResult

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值