Promise用法详解(一)

Promise用法详解(一)Promise基本概念Promise是一个构造函数,所以可以new出一个Promise的实例在Promise上有两个函数resolve(成功之后的回调函数)和reject(失败后的回调函数)在Promise构造函数的prototype属性上,有一个.then()方法。所以只要是Promise构造函数创建的实例,都可以访问到.then()方法Promise表示一个一…

大家好,又见面了,我是你们的朋友全栈君。

Promise

基本概念
  1. Promise是一个构造函数,所以可以 new 出一个Promise的实例
  2. 在Promise上有两个函数 resolve(成功之后的回调函数)和 reject(失败后的回调函数)
  3. 在Promise构造函数的prototype属性上,有一个 .then() 方法。所以只要是Promise构造函数创建的实例,都可以访问到 .then()方法
  4. Promise表示一个一步操作,每当我们new一个Promise的实例,这个实例就代表具体的异步操作。
  5. Promise创建的实例,是一个异步操作,这个异步操作结果,只有两种结果
  • 状态1:异步执行成功,需要在内部调用成功的回调函数resolve把结果返回给调用者
  • 状态2:异步执行失败,需要在内部调用失败的回调函数reject把结果返回调用者
  • 由于Promise的实例是一个异步操作,所以内部拿到操作结果后,无法使用return把操作结果返回给调用者,这个时候只能使用回调函数的形式,把成功或失败的结果,返回给调用者
  1. 我们可以在new出来的Promise实例上,调用 .then()方法,预先为这个Promise异步操作,指定成功(resolve)和失败(reject)回调函数
形式上和具体的Promise异步操作的区别
let parmise = new Promise()

注意:上面new出来promise,只代表形式上的一个异步操作。就是说,我们只知道他是一个 异步操作,但做什么具体异步事情目前还不清楚。

let promise = new Promise(function() {
    // 这个function内部写的就是具体的异步操作
}

上面则是一个具体的异步操作,其中使用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)           
        })
    })
})

这个时候就出现了一个问题: 回调地狱
这时你想起来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)
})
 

也成功完成需求这里写图片描述

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)
})

结果如图这里写图片描述
需求:前面的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)
})

结果如图这里写图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/149071.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SD/MMC卡介绍

    SD/MMC卡介绍1.1.什么是MMC卡MMC:MMC就是MultiMediaCard的缩写,即多媒体卡。它是一种非易失性存储器件,体积小巧(24mm*32mm*1.4mm),容量大,耗电量低,传输速度快,广泛应用于消费类电子产品中。1.2.什么是SD卡SD:SD卡为SecureDigitalMemoryCard,即安全数码卡。它在MMC的基础上发展而来,增加

    2022年4月29日
    102
  • 基于Windows的安全帽识别算法「建议收藏」

    基于Windows的安全帽识别算法「建议收藏」现如今越来越重视安全生产,各个企业也都采取各种措施保障员工的安全生产从而保障了企业的利益。但是依然存在着在岗工人不佩戴安全帽从事危险作业,未佩戴安全帽作业而造成的伤亡时有发生。安全帽佩戴管理成为一大难点,为降低管理难度提高在岗人员安全意识,可在各种生产现场部署安全帽识别仪实时视频检测预警在岗工人是否按照要求做好安全防范措施作业。真正做到安全生产信息化管理,做到事前预防事中常态监测,事后规范管理。…

    2022年5月19日
    40
  • Java大数据学习路线图

    Java大数据学习路线图Java大数据学习路线图准备篇适用/适合人群:适合基础小白在这里还是要推荐下我自己建的大数据学习群:199427210,群里都是学大数据开发的,如果你正在学习大数据,小编欢迎你加入,大家都是软件开发党,不定期分享干货(只有大数据软件开发相关的),包括我自己整理的一份最新的大数据进阶资料和高级开发教程,欢迎进阶中和进想深入大数据的小伙伴加入。目标:掌握JavaS…

    2022年5月8日
    40
  • split 方法_subsequence和substring的区别

    split 方法_subsequence和substring的区别1,split方法split()方法用于把一个字符串分割成字符串数组。例如:数据中现在有这样一个结果128b8f730592cc8db33ea52985127d44,44bee6555822d8321d2d1a2c1ac3b2cf,b2f939f26e512934e165f3e784cc74ca,我需要把这个字符串变成数组 console.log(res.result.produc…

    2022年9月25日
    4
  • c语言定义函数和声明函数_C语言中用户定义函数的类型

    c语言定义函数和声明函数_C语言中用户定义函数的类型c语言定义函数和声明函数C语言中用户定义函数的类型(TypeofUser-definedFunctionsinC)Therecanbe4differenttypesofuser-definedfunctions,theyare:可以有4种不同类型的用户定义函数,它们是:Functionwithnoargumentsandnoreturnv…

    2022年6月22日
    28
  • SQLite数据库中文乱码处理「建议收藏」

    SQLite数据库中文乱码处理「建议收藏」通过SQLiteAdministrator等工具生成的数据库文件,放入到Android中,查询记录怎么也查不出来,后来发现是编码错误,SQLiteAdministrator不支持utf编码,所以存储的中文会出现乱码的情况,处理方法如下:SQLiteDatabasedb=dbHelper.getWritableDatabase();Cursorcursor

    2025年8月26日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号