js中分为同步和异步代码
js 代码执行规则为:
- 从上到下执行
- 同步代码马上执行
- 异步代码先放到异步代码队列中,等待同步代码执行完毕后再去执行
使用promise进行修饰改造(使用node进行演示)
如果像下面代码:
const fs = require('fs')
var a = ''
fs.readFile('./fs/fs.text', 'utf8', (error, res) => {
a = res
})
console.log(a)
//此时的输出,a变量肯定是空的,因为读取文件的过程是异步,所以异步还没有执行,console.log(a)就已经执行了,就会输出a的原有值(a的原有值为空字符串)
那么怎么解决这种问题呢
方式一:
缺点:就会形成 回调地狱 ,代码少还行,如果后面很多逻辑都要使用这个res的值,那么回调函数里面就会出现好多代码,结构混乱,不够清晰
const fs = require('fs')
var a = ''
fs.readFile('./fs/fs.text', 'utf8', (error, res) => {
a = res
console.log(a)
//将console.log(a)放到回到函数里面此时a的值肯定是res
})
方式二:
使用Promise进行修饰
还是不够完美,then和catch又是异步
const fs = require('fs')
function ReadFile (url) {
//创建promise实例,return返回它
return new Promise((resolve, reject) => {
fs.readFile(url, 'utf8', (error, res) => {
resolve(res) //成功返回
reject(error)//错误返回
})
})
}
//调用后声明变量接收(值为promise)
let results = ReadFile('./fs/fs.text')
//then是成功后要执行的方法,方法里面的callback的参数对应的是promise实例中的reslove中的参数,
results.then(res => {
console.log(res)
})
//catch方法是有错时要执行的方法,方法里面的callback的参数对应的是promise实例中的reject中的参数,
.catch(res => {
console.log(res)
})
方式三:
使用async和await (语法糖)
推荐!!!
await只能在异步中使用并且await只能接收Promise,而async可以一个方法修饰成异步,再使用Promise进行结合使用
const fs = require('fs')
function ReadFile (url) {
//创建promise实例,return返回它
return new Promise((resolve, reject) => {
fs.readFile(url, 'utf8', (error, res) => {
resolve(res) //成功返回
reject(error)//错误返回
})
})
}
async function f1 () {
let a = await ReadFile('./fs/fs.text')
console.log(a)
}
f1()