上节课我们介绍了Promise
是什么以及为什么我们要使用Promise
,而且通过案例来介绍了Promise
的基本使用方法以及工作流程,那么这节课我们来做一下Promise
的实践练习。
fs
文件操作
大家可能有些人知道fs
的用途是什么,这是一个可以从计算机硬盘读取文件的一个模块,我们现在有一个需求,要求我们来读取当前目录下的resource
目录中的content.txt
文件。那么我们怎么处理?
纯回调函数实现
const fs = require("fs"); fs.readFile("./resource/content.txt", (err, data) => { if (err) throw err; console.log(data); });
首先我们用纯回调函数来实现一下,我们先是导入了fs
库,然后调用readFile
方法来读取文件,这个方法接收两个参数,第一个是文件路径,第二个是一个回调函数,这个回调函数中也接收两个参数,一个是异常,一个是读取到的文件内容。我们来看回调函数体,如果有异常出现,就抛出异常,否则就打印文件内容。我们来执行一下这段代码。
我们来看一下,代码执行成功了,打印出了一串buffer
,这是看不见文件内部的实际内容的。那么我们在data
后面加一个toString()
专成字符串输出再看一下
这次我们看见我们打印出来的文件内容中就写了test file
这两个单词。
Promise
方式实现
那么我们如果用Promise
来封装这个操作应该怎么写呢?我们来看代码:
const fs = require("fs"); let p = new Promise((resolve, reject) => { fs.readFile("./resource/contentt.txt", (err, data) => { if (err) { reject(err); } else { resolve(data); } }); }); p.then( value => console.log(value.toString()), reason => console.log(reason) );
我们来看,第一步,我们先来实例化一个Promise
对象,接收一个函数作为参数,函数接收两个参数,resolve
和reject
函数,然后函数体中包裹一个异步操作,就是我们的文件读取操作。然后还是像之前一样的判断,如果有异常,这次我们就不直接抛出异常了,我们调用reject
函数,代表着异步任务失败,并且把err
对象传给reject
函数。如果没有异常,那就说明异步任务成功了,调用resolve
函数,并且将data
传给resolve
函数。
接下来我们就可以调用Promise
对象的then
方法了,then
方法接收两个函数,第一个函数为Promise
对象状态为成功时调用,并且接收到异步任务成功时的结果值,然后我们打印出来。第二个函数为Promise
对象状态为失败时调用,也会接收到异步任务失败时的结果值,并且打印出来。
那么我们来看一下结果。大家如果看得仔细一点的话就会发现,上面那段代码我故意把文件路径写错了。我们来看一下执行结果:
我们先是正确的时候执行了一次,我们看见控制台中成功打印出了文件中的内容,然后我们把文件路径写错再执行一次,这次打印出了我们的错误对象。
以上就是fs
读取文件的两种实现形式的练习。
Ajax
请求
前面我们做了一个读取文件的练习,那么接下来我们来做一个发送ajax
请求的练习,我们现在有这么一个需求:
我们现在这个页面上面有一个按钮,当我们点击按钮之后就会发送一个ajax
请求,并且把请求结果打印在控制台中。
Ajax
方式
那么我们怎么处理?如果直接用ajax
不用Promise
的话就是ajax
的固定流程:
<body> <div class="container"> <h2 class="page-header">Promise AJAX</h2> <button id="btn" class="btn btn-primary">Click to send ajax</button> </div> <script> const btn = document.getElementById("btn"); btn.addEventListener( "click", () => { const xhr = new XMLHttpRequest(); xhr.open("GET", "https://api.apiopen.top/getJoke"); xhr.send(); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { console.log(xhr.response); } else { console.log(xhr.status); } } }; }); </script> </body>
我们先定位到按钮元素,然后绑定点击事件,在点击事件中,我们首先实例化一个xhr
对象,然后设置我们发送的请求方式和请求URL
,然后发送请求,接下来我们要处理响应结果。判断readyState
是不是为4,如果为4,再判断请求状态码是不是为2xx
,因为状态码只要是2开头的,都代表请求成功了。所以说我们并不是只判断200,如果为2xx
那么答应响应体,否则打印状态码。那么我们来看一下实际效果:
我们看见了控制台中打印出了很多接口返回的数据。这就是我们完全使用ajax
来发送请求。
Promise
方式
那么上面的这一部分如何使用Promise
的方式来实现呢?
btn.addEventListener( "click", () => { let p = new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open("GET", "https://api.apiopen.top/getJoke"); xhr.send(); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { resolve(xhr.response); } else { reject(xhr.status); } } } }); p.then( value => console.log(value), reason => console.log(reason) ); });
我们来看代码,首先实例化一个Promise
对象,并传入一个函数,该函数接收两个函数作为参数,这个函数的函数体包裹一个异步操作,那么就是说ajax
请求的部分都封装在这个函数体中,然后依然还是判断状态码,如果状态码是2xx
那么执行resolve
函数,并把响应体传给resolve
函数,否则说明请求失败,调用reject
函数并把状态码传给reject
函数,接下来我们调用then
方法,在then
方法中定义两个函数,分别接收成功与失败时的结果值并打印到控制台中。
那么我们这么写的效果是什么样子呢?我们来看一下:
首先我们故意将url
的路径写错,然后接口报了404,控制台中也成功打印了404,那么接下来我们把url
路径修改成正确的路径再来请求看一下:
这一次成功打印了很多接口返回的信息。
以上便是Promise
对ajax
请求的一个封装,大家看是不是就那么一个固定的路数?只要把我们的异步操作放到Promise
对象里,操作失败就调reject
函数,成功就调resolve
函数,然后再调用Promise
对象的then
方法,在then
方法中定义两个函数,成功了执行第一个函数,否则执行第二个函数
Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.
Link of this article:https://work.lynchow.com/article/use_promise_test/