promise

145 阅读4分钟

转自blog.csdn.net/Svik_zy/art…

🐸 一 promise是什么?
es6提供了原生对象promise。
promise的意思是未来将要做的事,用来传递异步操作的消息。

1.抽象表达
promise是ES6新的API
promise是JS进行异步编程的新的解决方案,以前单纯使用回调函数
2.具体描述
从语法来说,promise是一个构造函数 从功能来说,promise对象用来封装一个异步操作并获得其成功/失败的结果。

 构造函数是什么:一种特殊的方法,定义构造函数时首字母要大写。
 任何函数都可以作为构造函数存在,与普通函数的区分主要从功能进行区分。
 其主要功能是初始化对象,特点是和new一起使用。
 new是在创建对象,从无到有。构造函数是给初始化对象添加属性和方法。
🐸二 异步编程

同步任务:在主线程队列中,只有前一个任务完成才会执行下一个任务。
异步任务:不进入主线程队列,而是进入异步队列,前一个任务的完成与否不影响后一个任务的执行。

setTimeout(function (){ 
    console.log('执行了回调函数') 
},3000) 
console.log(111)

// 111 
// 执行了回调函数

代码中呈现的是`异步操作`,顺序是:先打印出111,定时器时间到,再执行定时器内的回调

下面是一些常见的异步操作:

  • fs文件操作:
require('fs').readFile('./index.html', (err,data)=>{})
  • 数据库操作
  • AJAX
$.get('/server', (data)=>{})
  • 定时器
🐸三 promise的状态改变

promise对象有2个特点:
1.对象的状态不受外界影响。Promise对象代表一个异步操作,有3个状态:

pending: 初始状态,非成功或失败状态
resolved:操作成功完成
reject:操作失败

只有异步操作的结果,可以决定当前是哪种状态,任何其他手段都无法改变promise状态,这也是promise名字的含义:「承诺」。 2.一旦状态改变,就不会再变,任何时候都可以得到这个状态。也就是说,状态改变只有这2种情况:

  • pending -> resolved
  • pending -> reject

**说明:
只有这2种变化,且一个promise只变化一次。
无论是成功、失败,都会有一个结果数据。

状态变化之后就凝固了。就算你再加回调函数,也只会再次得到原结果。这与事件(Event)完全不同,事件错过之后再监听是得不到结果的。

🐸四 promise的优缺点

优点:

有了promise,可以把异步操作清晰明了的写出来,避免旧时的回调函数层层嵌套。
promise提供统一的接口,使异步操作更简单。

缺点:

无法取消:一旦新建就会立即执行,无法在中途取消。
如果不设置回调函数,promise内部抛出的错误,无法反应到外部。
在pending状态时,无法得知目前函数执行到哪个状态了(是刚开始还是即将结束了).
🐸五 promise的基本流程
stateDiagram-v2
newPromise(),pending状态,执行异步操作 --> promise对象resolved状态
newPromise(),pending状态,执行异步操作 --> promise对象reject状态
promise对象resolved状态 --> 回调onResolved(),.then()
promise对象reject状态 --> 回调onReject(),.then()/.catch()
回调onResolved(),.then() --> 新的promise对象
回调onReject(),.then()/.catch() --> 新的promise对象

🐸六 promise的示例

抽奖系统:点击抽奖按钮,一秒后展示是否中奖(30%概率中奖),恭喜或者再接再厉。

//随机数
methords: {
    rand(m, n){
        let num = Math.ceil(Math.random() * (n - m + 1)) + m - 1
    }
    fn_click(){
        const  p =  new Promise((resolve, reject) => {
            setTimeout(() =>{
                let n = this.rand(1100)
                if(n < 30){
                    resolve(n)
                } else {
                    reject(n)
                }
            }, 1000)
        })
        p.then(value => {
            alert('您的中奖号码为' + value)
        }, reason => {
            alert('再接再厉')
        })
    },
    
}

Promise的.then方法
  1. .then方法的返回值也是一个Promise对象。

对于已经实例化过的Promise对象可以调用myPromise.then(),传入resolve 和 reject 方法作为回调。

  1. 当需要串联多个任务时,可以使用.then 方法。
let p =  new Promise( (resolve, reject) => {
    resolve('OK')
})
p.then(value =>{
    return new Promise( (resolve, reject) => {
        resolve('success')
    })
}).then(value => {
    console.log(value)
}).then(value => {
    console.log(value)
})

解释: p是一个Promise对象,状态resolve,返回值是OK。

第一个.then,接收p这个promise的成功回调,这个回调内部的返回值又是一个promise,回调promise的状态是成功,值是success,所以可以用.then接收这个成功

第二个 .then,返回的也是一个promise,接收第一个.then返回的promise的成功返回值success,所以console'success'。但是在.then的回调内部没有return值,所以默认返回值为undefined,undefined不是一个promise,所以状态是resolve,参考https://blog.csdn.net/weixin_59731784/article/details/124532246

第三个.then,返回的也是一个promise,因为第二个.then返回值是undefined,不是一个promise,所以可以从.then获取值,返回值是undefined。所以console undefined

Promise的.catch方法

上面的写法可以简化为.cetch方法

p.then(value => {
    alert('您的中奖号码为' + value)
}).catch(reason => {
    alert('再接再厉')
})

总结:promise.then方法接受2个参数,成功value和失败reason。promise.then.catch方法,前面成功回调,catch捕捉失败回调。