Promise 介绍
Promise 是一个构造函数,是异步编程的一种解决方案。所谓Promse,它本身就是一个容器,里面保存着异步操作的结果,对的,这和回调函数类似。
Promise 容器本身不是异步的,而里面封装一个异步任务。他有三种状态,即:1.pending(进行中)、2.resolved(成功)、3.rejected(失败)。状态只能变为一种。
Promise 获取文件信息
const fs = require('fs'); let p1 = new Promise((resolve, reject) => { fs.readFile('./data/a.txt', 'utf8', (error, data) => { if (error) { reject(error); } else { resolve(data); } }); }); let p2 = new Promise((resolve, reject) => { fs.readFile('./data/b.txt', 'utf8', (error, data) => { if (error) { reject(error); } else { resolve(data); } }); }); let p3 = new Promise((resolve, reject) => { fs.readFile('./data/c.txt', 'utf8', (error, data) => { if (error) { reject(error); } else { resolve(data); } }); }); // then 的链式编程 p1 .then(data => { console.log('a的数据', data); // 当 p1 读取成功的时候 // 当前函数中 return 的结果就是后面的 then 中 Function 接收到 // 当你 return 123 后面就接收到 123 // 没有 return,后面接收到的就是 undefined // 上面那些 return 的数据没什么软用 // 真正有用的事,return 一个 Promise 对象 // 当 return 一个 Promise 对象的时候,后续的 then 中的方法的第一个参数会作为 这个对象的结果 return p2; }, error => { console.log('读取文件a失败了', error); }) .then(data => { console.log('b的数据', data); return p3; }, error => { console.log('读取文件b失败了', error); }) .then(data => { console.log('c的数据', data); }, error => { console.log('读取文件c失败了', error); })
显然,上面这个例子显得特别麻烦!
选择,让我们封装 Promise
const fs = require('fs'); const pReadFile = (filePath) => { return new Promise((resolve, reject) => { fs.readFile(filePath, 'utf8', (error, data) => { if (error) { reject(error); } else { resolve(data); } }); }); }; pReadFile('./data/a.txt') .then(data => { console.log('a文件数据: ', data); return pReadFile('./data/b.txt'); }) .then(data => { console.log('b文件数据: ', data); return pReadFile('./data/c.txt'); }) .then(data => { console.log('c文件数据: ', data); });
Promise 配合 AJAX 获取信息
data.json文件:
{ "users": [ { "id": 1, "username": "admin-1", "age": 18, "job": 2 }, { "id": 2, "username": "admin-2", "age": 18, "job": 4 }, { "id": 3, "username": "admin-3", "age": 18, "job": 5 } ], "jobs": [ { "id": 1, "name": "学生" }, { "id": 2, "name": "老师" }, { "id": 3, "name": "司机" }, { "id": 4, "name": "演员" }, { "id": 5, "name": "工程师" }, { "id": 6, "name": "程序员" } ] }
代码:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8" /> <title>独秀不爱秀</title> </head> <body> <form id="user-form"></form> <script type="text/html" id="tpl"> <div> <label for="">用户名</label> <input type="text" value="{{ user.username }}"> </div> <div> <label for="">年龄</label> <input type="number" value="{{ user.age }}"> </div> <div> <label for="">职业</label> <select name="" id=""> {{ each jobs }} {{ if user.job === $value.id }} <option value="{{ $value.id }}" selected>{{ $value.name}}</option> {{ else }} <option value="{{ $value.id }}">{{ $value.name}}</option> {{ /if }} {{ /each }} </select> </div> </script> <script src="node_modules/art-template/lib/template-web.js"></script> <script src="node_modules/jquery/dist/jquery.js"></script> <script type="text/javascript"> /** * 既可以实现 callback 获取 * 也可以实现 .then 方式获取 */ const pGet = (url, callback) => { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.onload = () => { resolve(JSON.parse(xhr.responseText)); callback && callback(JSON.parse(xhr.responseText)); } xhr.onerror = (error) => reject(error); xhr.open('get', url); xhr.send(); }); }; let currentData = {}; pGet('./data.json') .then((data) => { currentData.user = data.users[0]; return data.jobs; }) .then((jobsData) => { currentData.jobs = jobsData; let htmlStr = template('tpl', currentData); document.getElementById('user-form').innerHTML = htmlStr; }); </script> </body> </html>