1.js中多个异步调用(接口,读取文件)时没有顺序,若业务现在要求有顺序的调用,就只能嵌套回调,如果嵌套回调3个以下代码量还不是很多,还可以凑乎,超过3个后重复代码多,可维护性差,代码丑陋ugly,就造成了callback hell,所以Es6出了promise解决此问题,jquery支持promise功能,node中的mongoose支持。
使用场景:注册功能前查询用户名字是否存在,手机号是否存在等等,页面的select多级联动(查询省市县)下拉框选择后还需要查询数据。
示例代码:
var fs = require('fs')
fs.readFile('./data/a.txt', 'utf8', function (err, data) { if (err) { // return console.log('读取失败') // 抛出异常 // 1. 阻止程序的执行 // 2. 把错误消息打印到控制台 throw err } console.log(data) fs.readFile('./data/b.txt', 'utf8', function (err, data) { if (err) { // return console.log('读取失败') // 抛出异常 // 1. 阻止程序的执行 // 2. 把错误消息打印到控制台 throw err } console.log(data) fs.readFile('./data/c.txt', 'utf8', function (err, data) { if (err) { // return console.log('读取失败') // 抛出异常 // 1. 阻止程序的执行 // 2. 把错误消息打印到控制台 throw err } console.log(data) }) }) })
promise容器概念:pending正在进行后有2种状态,要么成功变成resolved,要么失败变成rejected.
promiseAPI代码图示:
promise的链式调用
1.示例代码:
1)使用promise未封装url版本
var fs = require('fs')
var p1 = new Promise(function (resolve, reject) { fs.readFile('./data/a.txt', 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) })
var p2 = new Promise(function (resolve, reject) { fs.readFile('./data/b.txt', 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) })
var p3 = new Promise(function (resolve, reject) { fs.readFile('./data/c.txt', 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) })
p1 .then(function (data) { console.log(data) // 当 p1 读取成功的时候 // 当前函数中 return 的结果就可以在后面的 then 中 function 接收到 // 当你 return 123 后面就接收到 123 // return 'hello' 后面就接收到 'hello' // 没有 return 后面收到的就是 undefined // 上面那些 return 的数据没什么卵用 // 真正有用的是:我们可以 return 一个 Promise 对象 // 当 return 一个 Promise 对象的时候,后续的 then 中的 方法的第一个参数会作为 p2 的 resolve // return p2 }, function (err) { console.log('读取文件失败了', err) }) .then(function (data) { console.log(data) return p3 }) .then(function (data) { console.log(data) console.log('end') })
2)使用promise封装url后版本
var fs = require('fs')
function pReadFile(filePath) { return new Promise(function (resolve, reject) { fs.readFile(filePath, 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) }) }
pReadFile('./data/a.txt') .then(function (data) { console.log(data) return pReadFile('./data/b.txt') }) .then(function (data) { console.log(data) return pReadFile('./data/c.txt') }) .then(function (data) { console.log(data) })