zoukankan      html  css  js  c++  java
  • 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把操作结果返回给调用者,这个时候只能使用回调函数的形式,把成功或失败的结果,返回给调用者

       6.我们可以在new出来的Promise实例上,调用 .then()方法,预先为这个Promise异步操作,指定成功(resolve)和失败(reject)回调函数

    形式上和具体的Promise异步操作的区别
    1 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)
    })

    也成功完成需求result

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

    结果如图result

    需求:前面的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)
    })

    结果如图result

  • 相关阅读:
    2020年7月15日Java学习日记
    2020年7月14日Java学习日记
    2020年7月13日Java学习日记
    2020年7月12日Java学习日记
    2020年7月11日Java学习日记
    2020年7月10日Java学习日记
    2020年7月9日Java学习日记
    2020年7月8日Java学习日记
    链式栈(Chain stack)
    Codeforces-1375-D-Replace by MEX
  • 原文地址:https://www.cnblogs.com/junjun-001/p/14537275.html
Copyright © 2011-2022 走看看