比如说要打印当前目录下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) } )