Promise用法详解(一)

本文详细介绍了Promise的基本概念、执行时机以及如何通过.then()和.catch()处理异步操作的成功与失败情况,通过实例展示了如何使用Promise解决回调地狱问题,包括异常捕获的两种方式及其适用场景。
摘要由CSDN通过智能技术生成

 

zero________________ 2018-08-08 16:32:50  17863  收藏 53
分类专栏: ECMAScript 文章标签: ES6 Promise catch resolve reject
版权
Promise
基本概念
Promise是一个构造函数,所以可以 new 出一个Promise的实例
在Promise上有两个函数 resolve(成功之后的回调函数)和 reject(失败后的回调函数)
在Promise构造函数的prototype属性上,有一个 .then() 方法。所以只要是Promise构造函数创建的实例,都可以访问到 .then()方法
Promise表示一个一步操作,每当我们new一个Promise的实例,这个实例就代表具体的异步操作。
Promise创建的实例,是一个异步操作,这个异步操作结果,只有两种结果
状态1:异步执行成功,需要在内部调用成功的回调函数resolve把结果返回给调用者
状态2:异步执行失败,需要在内部调用失败的回调函数reject把结果返回调用者
由于Promise的实例是一个异步操作,所以内部拿到操作结果后,无法使用return把操作结果返回给调用者,这个时候只能使用回调函数的形式,把成功或失败的结果,返回给调用者
我们可以在new出来的Promise实例上,调用 .then()方法,预先为这个Promise异步操作,指定成功(resolve)和失败(reject)回调函数
形式上和具体的Promise异步操作的区别
let parmise = new Promise()
1
注意:上面new出来promise,只代表形式上的一个异步操作。就是说,我们只知道他是一个 异步操作,但做什么具体异步事情目前还不清楚。

let promise = new Promise(function() {
    // 这个function内部写的就是具体的异步操作
}
1
2
3
上面则是一个具体的异步操作,其中使用function制定一个具体的异步操作

Promise的执行时机
每当new一个Promise实例的时候,除了会得到一个promise实例之外,还会立即调用我们为Promise构造函数传递的那个function,执行function中的异步代码
所以在使用Promise时我们可以用函数进行包裹,使其按需执行
通过 .then()指定回调函数的时候,成功的回调函数必须传,失败的回调可以省略

有了前面的这些铺垫我们来体验一下Primise的魅力
需求 此时我们有一个简单的需求,需要去依次去读取一些文件的内容。在没有学习Promise之前我们可能这样

const fs = require('fs')
// 形参依次代表,读取路径,成功回调,失败回调
function getFileByPath(fpath, succCb, errCb) {
    fs.readFile(fpath, 'utf-8', (err, dataStr) => {
        if (err) return errCb(err)
        succCb(dataStr)
    })
}

// 依次读取
getFileByPath('./1.txt', function (data) {
    console.log(data)
    getFileByPath('./2.txt', function (data) {
        console.log(data)
        getFileByPath('./3.txt', function (data) {
            console.log(data)           
        })
    })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
这个时候就出现了一个问题: 回调地狱
这时你想起来Pramise不就是为了来解决回调地狱的嘛,于是。

const fs = require('fs')
function getFileByPath(fpath) {
    return new Promise(function (resolve, reject) {
        fs.readFile(fpath, 'utf-8', (err, dataStr) => {
            if (err) return reject(err)
            resolve(dataStr)
       })
   })
}

// 依次读取
// 再上一个 .then中,返回一个promise实例,可以继续使用下一个 .then来处理
getFileByPath('./1.txt')
    .then(function (data) {
     console.log(data)
     return getFileByPath ('./2.txt')
 })
.then(function (data) {
    console.log(data)
    return getFileByPath('./3.txt')
})
    .then(function (data) {
    console.log(data)
})
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
也成功完成需求

Promise中异常捕获两种方式的使用场景
需求 :前面的Promise执行失败,但是不要影响后续promise正常执行。

此时可以单独为每个promise通过.then()指定一下失败的回调
const fs = require('fs')
function getFileByPath(fpath) {
    return new Promise(function (resolve, reject) {
        fs.readFile(fpath, 'utf-8', (err, dataStr) => {
            if (err) return reject(err)
            resolve(dataStr)
       })
   })
}

// 依次读取
// 注意此处我们写了一个根本不存在文件路径
getFileByPath('./11111111.txt')
    .then(function (data) {
     console.log(data)
     return getFileByPath ('./2.txt')
    }, function (err) {
        console.log('这是失败的结果:' + err.message)
        // return一个新的 Promise
        return getFileByPath('./2.txt')
 })
.then(function (data) {
    console.log(data)
    return getFileByPath('./3.txt')
})
    .then(function (data) {
    console.log(data)
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
结果如图
需求:前面的Promise执行失败,后面Promise依赖于前面Promise执行结果,如果前面失败了后面也没有继续执行下去的意义了。

此时可以使用 .catch()进行异常捕获,只要前面Promise有任何一个执行失败,立即终止所有的Promise的执行,并马上进入catch中去处理Promise中抛出的异常。
const fs = require('fs')
function getFileByPath(fpath) {
    return new Promise(function (resolve, reject) {
        fs.readFile(fpath, 'utf-8', (err, dataStr) => {
            if (err) return reject(err)
            resolve(dataStr)
       })
   })
}

// 依次读取
getFileByPath('./1.txt')
    .then(function (data) {
        console.log(data)
        // 注意此处我们写了一个根本不存在文件路径
     return getFileByPath ('./22222.txt')
    })
    .then(function (data) {
    console.log(data)
    return getFileByPath('./3.txt')
})
   .then(function (data) {
    console.log(data)
})
// catch的作用: 如果前面有任何Promise执行失败,则立即终止所有Pormise执行,并进入Promise中去处理Promise抛出的异常     
    .catch(function (err) {
    console.log("catch来捕获:" + err.message)
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
结果如图
————————————————
版权声明:本文为CSDN博主「zero________________」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zero________________/article/details/81510764

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值