Promise、异步函数

node

同步、异步API的概念:

同步API:从上往下执行,当前代码执行完后,才会继续往下执行,范例:

console.log(1)
console.log(2)
// 1
// 2

异步API:当前代码的执行不会阻塞后续代码的执行,范例:

console.log(1)
setTimeout(() => {
	console.log(2)
}, 1000)
console.log(3)
// 1
// 3
// 等待1秒后
// 2

同步API我们是可以直接用返回值获取结果的,但是异步API是不行的,异步API需要用回调函数的形式,用回调函数的形参接收返回结果

console.log(1)
// 同步代码在执行时,这个setTimout也会执行,只不过回调函数当前不会调用,会先推入到异步回调队列中,等达到执行条件了,就会调用
setTimout(() => {
  console.log(2)
}, 1000)
console.log(3)

回调地狱:指的是多个依次的异步操作,说白了就是回调函数嵌套,当嵌套层次过多,不利于阅读和维护

Promise基本使用:

const fs = require('fs')
// 这个resolve和reject是我们自己定义名字,你可以改成其他,但是不推荐,业内约定俗成就叫这个
const p = new Promise((resolve, reject) => {
  fs.readFile('./hehe.txt', 'utf8', (err, data) => {
    if (err) {
      reject(err)
    } else {
      resolve(data)
    }
  })
})

p.then((data) => {
  // 异步API执行正确,拿到正确的数据
	// your code . do something...
}).catch((err) => {
  // 异步API执行异常,拿到错误的数据
  // your code... do something...
})
  • Promise就是用来解决回调地狱的,,它不是一个新的技术,只是一种手段,是异步编程的中间产物
    • 原理:把一个异步API封装起来,将异步API的结果以回调函数的形式传递出去
  • 可以通过new Promise( ( resolve, reject ) => { … }) 创建Promise实例
    • 注意:创建实例时,并不会执行( resolve, reject ) => { ... }回调函数,也就意味着内部的代码都不会执行,只有在调用then或catch方法的时候才会去调用
  • 可以通过resolve( result )方法传递正确的结果
  • 可以通过reject( err )方法传递错误的结果
  • 通过调用Promise实例的then(( result ) => { … })方法接收正确的结果
  • 通过调用Promise实例的catch(( err ) => { … })方法接收错误的结果

解决回调地狱:

const fs = require('fs')

// 想要依次读取1.txt,2.txt,3.txt的文件内容

// fs.readFile('./1.txt', 'utf8', (err, data) => {
//   console.log(data)
//   fs.readFile('./2.txt', 'utf8', (err, data) => {
//     console.log(data)
//     fs.readFile('./3.txt', 'utf8', (err, data) => {
//       console.log(data)
//     })
//   })
// })

// new Promise(cb) 实例时,并不会调用这个 cb 函数
// 只有在调用了Promise实例的then方法或catch方法,才会调用cb函数
const p1 = new Promise((yes, no) => {
  fs.readFile('./1.txt', 'utf8', (err, data) => {
    yes(data)
  })
})

const p2 = new Promise((yes, no) => {
  fs.readFile('./2.txt', 'utf8', (err, data) => {
    yes(data)
  })
})

const p3 = new Promise((yes, no) => {
  fs.readFile('./3.txt', 'utf8', (err, data) => {
    yes(data)
  })
})

// then函数的返回值 就是 其参数(回调函数)的返回值
p1.then(data => {
  console.log(data)
  return p2
}).then(data => {
  console.log(data)
  return p3
}).then(data => {
  console.log(data)
})

异步函数(ES7添加的):

  • async关键字:
    • 在普通函数前面加上async关键字,该普通函数就变成了异步函数
    • 异步函数的返回值会被包装成一个Promise实例
      • return传递正确的结果,相当于Promise里面的resolve函数
      • throw传递错误的结果,相当于Promise里面的reject函数,一旦抛出错误,后面的代码就不会执行了
  • await关键字:
    • await后面一般跟Promise实例(其实也可以跟其他的数据,如果是其他的数据,则直接返回),await可以阻塞后续的代码,等待Promise实例返回结果后,再继续向下执行
    • await可以直接拿到Promise实例的正确结果,错误结果需要用try ... catchcatch(err => err)(推荐用这个)来获取
    • await只能出现在异步函数(亲爸爸)中

范例:用async、await关键字改造依次读取1.txt、2.txt、3.txt文件的代码:

const fs = require('fs')
// promiseify可以将node中现有的基于回调函数形式的异步API,改造成返回Promise实例的函数
const { promiseify } = require('util')

// fs.readFile('./1.txt', 'utf8', (err, data) => { ... })
const readFileOfPromise = promiseify(fs.readFile)

(async () => {
 	const data1 = await readFileOfPromise('./1.txt', 'utf8')
  console.log(data1)
  const data2 = await readFileOfPromise('./2.txt', 'utf8')
  console.log(data2)
  const data3 = await readFileOfPromise('./3.txt', 'utf8')
  console.log(data3)
})()
代码块演示

在这里插入图片描述

异步执行机制图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值