JavaScript ES6 Promise

1、回调地狱问题:

nodejs的api大都是单线程异步模型,调用函数后,结果会通过回调函数来处理。

因此容易出现多层回调函数相互嵌套的现象,这种现象被称为:回调地狱。

这种代码可读性差,可维护性差。

在ES6中提供了Promise编程规范,用于解决回调地狱的问题。

2、Promise基本概念:

(1)Promise是一个构造函数

可以创建Promise的实例 const p = new Promise()

new出来的Promise实例对象,代表一个异步操作

(2)Promise.prototype上(原型链)有then()、catch()、fianlly()等方法

每一次new Promise()构造函数得到实例对象,都可以通过原型链访问then()等方法

(3)then()方法用来预先指定成功和失败的回调函数

p.then(result => {}, error => {})

result回调函数是必须指定的,error回调函数是可省略的。

3、Promise基本使用:

(1)安装thenFs包

npm install then-fs

(2)要读取的文件,files目录下有三个文件

1.txt内容为:111

2.txt内容为:222

3.txt内容为:333

(3)使用Promise读取文件代码:

import thenfs from 'then-fs'

// 1、无法保证顺序
thenfs.readFile('./files/1.txt','utf-8').then(result => {
    console.log(result)
},error => {
    console.log(error.message)
})

thenfs.readFile('./files/2.txt','utf-8').then(result => {
    console.log(result)
},error => {
    console.log(error.message)
})

thenfs.readFile('./files/3.txt','utf-8').then(result => {
    console.log(result)
},error => {
    console.log(error.message)
})

执行结果可能是:

111
333
222

使用Promise的then方法实现:

如果上一个then()方法中返回了一个新的Promise实力对象,则可以通过下一个then()继续进行处理,通过then()方法的链式调用,就可以解决回调地狱问题:

import thenfs from 'then-fs'

// 2、保证顺序,使用then()链式调用
thenfs.readFile('./files/11.txt','utf-8').then(r1 => {
    console.log(r1)
    return thenfs.readFile('./files/2.txt','utf-8')
}).then( r2 => {
    console.log(r2)
    return thenfs.readFile('./files/3.txt','utf-8')
}).then(r3 => {
    console.log(r3)
}).catch(err => {
    console.log(err.message)
})

执行结果是:

111
222
333

这个执行结果,读取文件的顺序不会改变。

4、使用ES8的async和awati简化Promise代码:

在ES8中,提供了async/await 的api,可以简化Promise的then的链式调用。

import thenfs from 'then-fs'
// 3、使用async/await 简化Promise的调用
async function readFile(){
    let r1 = await thenfs.readFile('./files/1.txt','utf-8')
    console.log(r1)

    let r2 = await thenfs.readFile('./files/2.txt','utf-8')
    console.log(r2)

    let r3 = await thenfs.readFile('./files/3.txt','utf-8')
    console.log(r3)
}

readFile()

执行结果为:

111
222
333

注意事项:

如果在function中使用了await关键字,那么这个function必须用async修饰。

在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行。

原文地址:https://www.cnblogs.com/asenyang/p/15678513.html