文章目录
可以通过
Promise
来处理回调地域,嵌套函数太多不方便处理的问题
1. 基本语法
var fs = require('fs');
//在EcmaScript 中新增的一个 API Promise
//Promise 是一个构造函数
//创建Promise容器
// 1. Promise容器一旦创建,就开始执行里面的代码
var p1 = new Promise(function(resolve, reject){
fs.readFile('./data/a.txt','utf8',function(err,data){
if(err){
//调用 reject 就相当于调用 then 方法的第二个参数
reject(err)
}else{
// 这里的 resolve 方法实际上就是 then 方法传递的那个 function
resolve(data)
}
})
});
// 执行承若后,then 做指定操作
// then 方法接收的 function 就是容器中的 resolve
p1.then(function(data){
console.log(data)
},function(err){
console.log('读取文件失败',err)
})
2. Promise
异步调用链式编程
var p1 = new Promise(function(resolve, reject){
fs.readFile('./data/a.txt','utf8',function(err,data){
if(err){
//调用 reject 就相当于调用 then 方法的第二个参数
reject(err)
}else{
// 这里的 resolve 方法实际上就是 then 方法传递的那个 function
resolve(data)
}
})
});
var p2 = new Promise(function(resolve, reject){
fs.readFile('./data/b.txt','utf8',function(err,data){
if(err){
//调用 reject 就相当于调用 then 方法的第二个参数
reject(err)
}else{
// 这里的 resolve 方法实际上就是 then 方法传递的那个 function
resolve(data)
}
})
});
var p3 = new Promise(function(resolve, reject){
fs.readFile('./data/c.txt','utf8',function(err,data){
if(err){
//调用 reject 就相当于调用 then 方法的第二个参数
reject(err)
}else{
// 这里的 resolve 方法实际上就是 then 方法传递的那个 function
resolve(data)
}
})
});
p1
.then(function(data){
console.log(data);
// return 后得到的结果会在下一个 then 中接收到
// 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);
})
3. 封装Promise版本的readFile
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);
})
4. promise
应用场景
获取多个表的数据信息
//封装ajax`get`方法
function get(url, callback){
var oReq = new XMLHttpRequest();
//当请求加载成功之后要调用指定的函数
oReq.onload = function(){
//现在需要的到这里的oReq.responseText
callback(JSON.parse(oReq.responseText));
}
oReq.open("get", url, true);
oReq.send();
}
4.1 开启数据接口服务
可以对.json
文件数据进行测试
# 1. 安装 `json-server`
npm install -g json-server
# 2. 创建 .json 文件 data.json
# 3. 开启服务
json-server --watch data.json
4.2 ajax
地狱回调方式
get('http://localhost:3000/users/1', function(usersData){
get('http://localhost:3000/jobs',function(jobsData){
var htmlStr = template('tp1', {
user: usersData,
jobs: jobsData
});
//在表单上显示出来
document.querySelector('#user_form').innerHTML = htmlStr;
})
})
4.3 jquery
的promise
方法
//为了能同时获得两个表单的数据,所有将拿到的数据存储到data中
var data = {}
$.get('http://localhost:3000/users/1')
.then(function(users){
data.user = users;
return $.get('http://localhost:3000/jobs');
})
.then(function(jobs){
data.job = jobs;
var htmlStr = template('tp1',data);
document.querySelector('#user_form').innerHTML = htmlStr;
})
5. 封装具有 promise
属性的 get
方法
function get(url,callback){
return new Promise(function(resolve,reject){
var oReq = new XMLHttpRequest();
//成功时
oReq.onload = function(){
callback && callback(JSON.parse(oReq.responseText))
resolve(JSON.parse(oReq.responseText));
}
//失败时
oReq.onerror = function(err){
reject(err);
}
oReq.open("get", url, true);
oReq.send();
})
}
使用
var data = {}
get('http://localhost:3000/users/1')
.then(function(users){
data.user = users;
return get('http://localhost:3000/jobs');
})
.then(function(jobs){
data.job = jobs;
var htmlStr = template('tp1',data);
document.querySelector('#user_form').innerHTML = htmlStr;
})