臆想的
let fs = require('fs')
function readFile(filename){
...
}
let content = readFile('config.js')
// 针对读取到的内容举行操纵,比方打印文件内容
console.log(content)
臆想中,读取文件是有返回值的,将返回值,即文件内容,赋给一个变量,然后决议对读取到的内容举行响应的操纵,比方打印文件中的内容。
简而言之,臆想中,读取文件,打印文件是互相离开的。
回调
let fs = require('fs')
function readFile(filename, callback){
fs.readFile(filename, 'utf8', (err, data) => {
if(err){
throw new err
}
callback(data)
})
}
readFile('config.js', data => {
console.log(data)
})
实际上,在常常运用的回调中,读取文件和针对文件内容响应的操纵是在一起的,
你在请求读取文件的同时,还要申明猎取文件内容后干吗
这和习惯性头脑,你先把文件内容给我,至于我怎样处置惩罚,稍后再说
Promise
let fs = require('fs')
function readFile(filename) {
return new Promise(function (resolve) { // 这里的callback,是在run函数中通报的
fs.readFile(filename, 'utf8', (err, data) => {
if (err) {
reject(err)
}
resolve(data)
})
})
}
let content = readFile('config.js')
content.then(res => {
console.log(res)
})
// 对照臆想中的
let content = readFile('config.js')
// 针对读取到的内容举行操纵,比方打印文件内容
console.log(content)
运用Promise后,全部誊写逻辑最先和臆想中的很接近了,读取文件和对文件内容的操纵离开了
即经由历程运用Promise,能够将异步的操纵和对异步效果的处置惩罚,离开
来完成一个大略的假的Promise
let fs = require('fs')
function resolve(value) {
let _self = this
setTimeout(function () {
_self.callbacks.forEach(function (callback) {
callback(value);
})
}, 0)
// 保证在resolve实行之前,then要领都已注册
}
class FakePromise {
constructor(fn) {
// fn是个函数,内里包括异步,异步胜利
// Promise在new的历程中就已最先实行异步代码
// 异步代码实行完触发resolve,resolve作为异步代码的参数,它早已完成好
this.value = null
this.callbacks = []
fn(resolve.bind(this))
}
then(onFulfilled) {
this.callbacks.push(onFulfilled)
return this
}
}
function readFile(filename) {
return new FakePromise(function (resolve) {
fs.readFile(filename, 'utf8', (err, data) => {
if (err) {
return
}
resolve(data)
})
})
}
let content = readFile('config.js')
content.then(res => {
console.log(res)
})
如许看来,Promise和宣布-定阅形式有些相像。promise内部也有个事宜队列,经由历程then注册事宜,经由历程resolve触发。每一个promise在建立的时刻,就最先实行通报给它的函数,函数中会触发resolve,这个resolve就是去实行一切注册的事宜。
固然,实际上promise比这壮大的多,起首resolve实行一切注册的事宜会保证滞后实行,防止还没经由历程then注册完事宜,resolve就实行了
其次,在异步操纵胜利以后,经由历程then注册事宜,能够立马实行,这就需要给promise增加状况机制
...
then(onFulfilled) {
if (this.state === 'pending') {
this.callbacks.push(onFulfilled)
return this
}
onFulfilled(value)
return this
}
...
推断不是’pending’,就马上实行注册的函数
别的就是每一个then()要领,都邑返回一个新的promise
也许长如许
then(onFulfilled) {
return new Promise(...)
}
参考资料
生成器
let fs = require('fs')
function run(taskDef){
// 传入的taskDef是个生成器函数,实行后返回迭代器
let task = taskDef()
// 挪用迭代器的next()要领,最先taskDef函数中的代码,直至碰到yield,并将yield的值给予result
let result = task.next()
function step(){
if(!result.done){
if(typeof result.value === 'function'){
result.value((err, data)=>{
if(err){
result = task.throw(err)
return
}
result = task.next(data)
step()
})
// 这里的result.value(...){...}
// 挪用的是function(callback){fs.readFile(filename, 'utf8', callback)}
}else{
result = task.next(data)
step() // 推断使命是不是实行完
}
}
}
step()
// task.next(data) 继承实行生成器中的代码,并将值传回给触发此次next()的yield的等号左侧的变量
}
function readFile(filename){
return function (callback){ // 这里的callback,是在run函数中通报的
fs.readFile(filename, 'utf8', callback)
}
}
run(function*(){
let content = yield readFile('config.js') // 通报函数至run函数中,并由run通报参数挪用
// 对文件内容举行处置惩罚
console.log(content)
})
// 对照臆想中的
let content = readFile('config.js')
// 针对读取到的内容举行操纵,比方打印文件内容
console.log(content)
生成器函数能够住手函数实行,代码在yield readFile('copy.js')
处停息
异步使命的回调中挪用迭代器的next()要领,使生成器函数中的代码继承实行,并经由历程next()要领通报参数回至生成器函数中,异步使命完成,返回值已赋值给了content
Promise+generator
let fs = require('fs')
function run(taskDef){
// 传入的taskDef是个生成器函数,实行后返回迭代器
let task = taskDef()
// 挪用迭代器的next()要领,最先taskDef函数中的代码,直至碰到yield,并将yield的值给予result
let result = task.next()
function step(){
if(!result.done){
let promise = Promise.resolve(result.value)
promise.then(value => {
result = task.next(value)
step()
}).catch(err => {
result = task.throw(err)
step()
})
}
}
step()
// task.next(data) 继承实行生成器中的代码,并将值传回给触发此次next()的yield的等号左侧的变量
}
function readFile(filename){
return new Promise(function (resolve, reject){ // 这里的callback,是在run函数中通报的
fs.readFile(filename, 'utf8', (err, data) => {
if(err){
reject(err)
}
resolve(data)
})
})
}
run(function*(){
let content = yield readFile('config.js') // 通报函数至run函数中,并由run通报参数挪用
// 对文件内容举行处置惩罚
console.log(content)
})
console.log('先实行')
Async&await
是不是是和promise+generator很像
let fs = require('fs')
function readFile(filename) {
return new Promise(function (resolve) { // 这里的callback,是在run函数中通报的
fs.readFile(filename, 'utf8', (err, data) => {
if (err) {
reject(err)
}
resolve(data)
})
})
}
(async function test() {
let content = await readFile('copy.js')
console.log(content)
})()
参考资料
- 深切明白ES6