比如说要打印当前目录下a.txt b.txt c.txt种的内容,直接用读文件(回调)的方式来依次调用时存在问题的
无法保证输出顺序:
var fs = require("fs")
fs.readFile('./a.txt', 'utf8', function(error, data){
if(error){
return console.log(error)
}
console.log(data)
})
fs.readFile('./b.txt', 'utf8', function(error, data){
if(error){
return console.log(error)
}
console.log(data)
})
fs.readFile('./c.txt', 'utf8', function(error, data){
if(error){
return console.log(error)
}
console.log(data)
})
要解决这个问题,可以把方法嵌套起来,但这是不好的,会陷入“回调地狱”中
var fs = require("fs")
fs.readFile('./a.txt', 'utf8', function(error, data){
if(error){
return console.log(error)
}
console.log(data)
fs.readFile('./b.txt', 'utf8', function(error, data){
if(error){
return console.log(error)
}
console.log(data)
fs.readFile('./c.txt', 'utf8', function(error, data){
if(error){
return console.log(error)
}
console.log(data)
})
})
})
这种情况,可以用Promise解决。
Promise基本语法:
var fs = require("fs")
// Promise一旦new出来,就立即执行里面封装的代码
var p1 = new Promise(function(resolve, reject){
fs.readFile('./a.txt', 'utf8', function(error, data){
if(error){
// 承诺容器中的任务失败了,把容器的 Pending 状态变为 Reject
reject(error)
}else{
// 承诺容器中的任务成功了,把容器的 Pending 状态变为 Resolve
resolve(data)
}
})
})
// Promise执行完毕,就执行then方法
// then方法参数里的两个匿名function就是Promise里的resolve, reject参数
p1.then(
function(data){console.log(data)},
function(error){console.log(error)}
)
解决方法:
var fs = require("fs")
var p1 = new Promise(function(resolve, reject){
fs.readFile('./a.txt', 'utf8', function(error, data){
if(error){
reject(error)
}else{
resolve(data)
}
})
})
var p2 = new Promise(function(resolve, reject){
fs.readFile('./b.txt', 'utf8', function(error, data){
if(error){
reject(error)
}else{
resolve(data)
}
})
})
var p3 = new Promise(function(resolve, reject){
fs.readFile('./c.txt', 'utf8', function(error, data){
if(error){
reject(error)
}else{
resolve(data)
}
})
})
p1.then(
function(data){
console.log(data)
// 该方法可以return一个值,这个值会传递给下一个then的function的参数中
// 当 return 123, 后面就接收到123
// 当 return hello, 后面就接收hello
// 特别的,可以return一个Promise对象,比如说p2,这种就和return简单数据不一样了
// 当 return p2的时候,后面的then其实就是p2的then
return p2
},
function(error){
console.log(error)
return p2
}
).then(
function(data){
console.log(data)
return p3
},
function(error){
console.log(error)
return p3
}
).then(
function(data){
console.log(data)
},
function(error){
console.log(error)
}
)
这段代码还可以封装下
var fs = require("fs")
function readFile(filePath){
return new Promise(function(resolve, reject){
fs.readFile(filePath, 'utf8', function(error, data){
if(error){
reject(error)
}else{
resolve(data)
}
})
})
}
p1 = readFile('./a.txt')
p2 = readFile('./b.txt')
p3 = readFile('./c.txt')
p1.then(
function(data){
console.log(data)
return p2
},
function(error){
console.log(error)
return p2
}
).then(
function(data){
console.log(data)
return p3
},
function(error){
console.log(error)
return p3
}
).then(
function(data){
console.log(data)
},
function(error){
console.log(error)
}
)