先讲一下什么是回调地狱->callback hell,给你们看一张图片,回调地狱就是异步里面套了异步,下面的异步请求依赖于上一个异步请求的结果,必须嵌套进去,放在回调里面,就造成了回调地狱。为了解决这一问题,es6出现了一个api,就是promise.es6
下面咱们建立一个promise容器ajax
Promise容器一旦建立,就开始执行里面的代码api
var fs = require('fs')
new Promise(function(){
fs.readFile('./a.txt','utf8,function(err,data)'{
if(err){
//失败了,承诺容器中的任务失败了
console.log(err)
}else{
//认可容器中的任务成功了
console.log(data)
}
})
})
复制代码
下面咱们写一个输出,promise
console.log(1)
new Promise(function(){
console.log(2)
fs.readFile('./a.txt','utf8,function(err,data)'{
if(err){
//失败了,承诺容器中的任务失败了
console.log(err)
}else{
console.log(3)
//认可容器中的任务成功了
console.log(data)
}
})
})
console.log(4)
复制代码
输出的结果是什么? 1 2 4 3 为何会输出这样的呢?js执行顺序不是从上到下么?下面咱们简单分析下: 先输出1,紧接着遇到了new promise,当即执行,输出2,咱们上边提到了promise里面的任务是一个异步,因此执行输出4,当异步执行完后输出3bash
在此强调下:promise自己不是异步,可是内部每每都是封装一个异步任务。异步
下面咱们继续,上边提到了promise有成功和失败的状态,因此咱们把上边new promise的代码改写下。函数
var p1=new Promise(function(resolve,reject){
fs.readFile('./a.txt','utf8,function(err,data)'{
if(err){
//失败了,承诺容器中的任务失败了
//把容器的Pending状态变为失败Rejected
//调用reject就至关于调用了then方法的第二个参数函数
reject(err)
}else{
//认可容器中的任务成功了
//console.log(data)
//把容器的Pending状态变为成功resoved
//也就是说这里调用的resolve方法实际上就是then方法传递的那个function
resolve(data)
}
})
})
复制代码
上面的代码描述了咱们图中promise的概念,promise里面有一个异步任务,默认的状态pending成功了变成resoved,失败了变成rejected。 那么咱们如何使用它呢?ui
//p1就是promise
//当p1成功了而后(then)作指定的操做
//then方法接收的function就是容器中的resovle函数
p1
.then(function(data){
console.log(data)
},function(err){
console.log('读取失败了',err)
})
复制代码
以上是promise的基础语法, 我用图来表示下url
p1
.then(function(data)){
//当p1读取成功的时候,当前函数中return的结果就能够在后面的then中function接收到,
//当你return 123后面就接收到123
// return 'hello' 后面就接收到'hello'
//没有return 后面收到的就是undefined
//其实咱们真正用到的是能够return 一个promise对象
//当return 一个Promise对象的时候,后续的then中的方法的第一个参数会做为p2的resolve
// return 123
return p2
},function(err){
console.log(err)
})
.then(function(data){
console.log(data) //在此接收p2的返回值
})
var p2=new Promise(function()){
fs.readFile('./a.txt','utf8,function(err,data)'{
if(err){
reject(err)
}else{
resolve(data)
}
})
})
复制代码
咱们也能够多添加几个then去返回多个new Promise,这个就是then的链式调用 上图来描述下,spa
下面咱们封装一个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/test.txt')
.then(function(data){
console.log(data)
return pReadFile('./data/a.txt')
})
.then(function(data){
console.log(data)
return pReadFile('./data/b.txt')
})
.then(function(data){
console.log(data
})
复制代码
以上是一个简单完整的小例子。 如今咱们封装一个promise的ajax方法。
function pGet(url,callback){
return new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest()
xhr.onload = function(){
callback && callback(JSON.parse(pGet.responseText))
resolve(JSON.parse(pGet.responseText))
}
xhr.onerror = function(){
reject(err)
}
xhr.open("get",url,true)
xhr.send()
}
}
复制代码