1. 回调函数:回调函数就是一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数。这个过程就叫做回调。
const fs = require("fs")
fs.readFile("./name.txt","utf-8",(err,data)=>{
fs.readFile(data,"utf-8",(err,data)=>{
console.log(data) //666
})
})
2. Promise:promise是对上面说到的回调函数处理异步编程的一个进阶方案。首先Promise是CommandJS提出的一种规范,Promise的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。形如这种形式.
- bluebird
const Promise = require('bluebird'),
fs = require('fs');
Promise.promisifyAll(fs);
fs.readFileAsync('./name.txt', 'utf-8')
.then(data =>{return fs.readFileAsync (data,"utf-8")})
.then(data => console.log(data)); //666
- nodeJS中的promise
let fs = require("fs").promises
fs.readFile("./name.txt","utf8").then(data=>{
return fs.readFile(data,"utf8")
}).then(data=>{
console.log(data) //666
})
- 自己实现读文件方法(read)
let fs = require("fs")
function read(path) {
return new Promise((resolve,reject)=>{
fs.readFile(path,"utf8",(err,data)=>{
if(err) reject(err)
resolve(data)
})
})
}
read("./name.txt","utf8").then(data=>{
return read(data,"utf8")
}).then(data=>{
console.log(data) //666
})
3. Generator+co:
几个概念
- iterator迭代器:是一个对象,对象中有一个next函数,next函数返回一个对象,对象中包含两个参数(value,done)
function createIterator(items) {
let i = 0;
return{
next:()=>{
var done = (i >= items.length);
var value = !done ? items[i++] : undefined;
return{
done,value
}
}
}
}
let colors = ["red", "green", "blue"];
let iterator = createIterator(colors);
console.log(iterator.next()); //{ done: false, value: 'red' }
console.log(iterator.next()); //{ done: false, value: 'green' }
console.log(iterator.next()); //{ done: false, value: 'blue' }
console.log(iterator.next()); //{ done: true, value: undefined }
- generator:生成器,用来生成iterator,一般也是需要和promise配合使用的,yield产出, * 表明这是一个generator
function* read(){
yield "hello"
yield "world"
}
let it = read()
console.log(it.next()) //{ value: 'hello', done: false }
console.log(it.next()) //{ value: 'world', done: false }
console.log(it.next()) //{ value: undefined, done: true }
- for of :保证要循环的对象有一个iterator,set map array 均可以迭代
let colors = ["red", "green", "blue"];
for( value of colors){
console.log(value) //red green blue
}
- Array.from 可以把一个不是iterable的伪数组变成真实数据
let obj = {
0:"a",
1:"b",
[Symbol.iterator](){ // 让Obj是可迭代的
let index = 0;
return {
next:()=>{
return {
value:this[index],
done:this.length === index++
}
}
}
},
length:2
}
let realArray = [...obj]
console.log(realArray) //[ 'a', 'b' ]
console.log(Array.isArray(realArray))
解决方案
- 利用生成器解决异步问题
let fs = require("fs").promises
function* read (){
let res1 = yield fs.readFile("./name.txt","utf8")
let res2 = yield fs.readFile(res1,"utf8")
return res2
}
let it = read() //iterator
let {value,done} = it.next()
Promise.resolve(value).then(data=>{
console.log(data) //age.txt
let {value,done} = it.next(data)//{ value: Promise { <pending> }, done: false }
Promise.resolve(value).then(data=>{
console.log(data) // 666
})
})
- 利用生成器+promise来解决异步问题,可能会无限嵌套
let fs = require("fs").promises
function* read(){
let res = yield fs.readFile("./name.txt","utf-8")
yield fs.readFile(res,"utf-8")
}
let it = read()
let {value,done} = it.next()
Promise.resolve(value).then(data=>{
console.log(data) //age.txt
let {value,done} = it.next(data)
Promise.resolve(value).then(data=>{
console.log(data) //666
})
})
- generator + co来解决异步
let fs = require("fs").promises
let co = require("co");
function* read() {
let res1 = yield fs.readFile("./name.txt", "utf-8")
let res2 = yield fs.readFile(res1, "utf-8")
return res2;
}
console.log(co(read)) //Promise { <pending> }
co(read).then(data => {
console.log(data) // 666
},err=>{
console.log(err)
})
4.Async+await:async+await:generator的语法糖,async/await使得异步代码看起来像同步代码
let fs = require("fs").promises
async function read() {
let res1 = await fs.readFile("./name.txt", "utf-8")
let res2 = await fs.readFile(res1, "utf-8")
return res2;
}
read().then(data=>{
console.log(data) //666
},err=>{
console.log(err)
})