理解Promise对象

Promise对象:

  • 一个保存异步操作事件的对象
  • 三种状态,Pending、Fulfilled、Rejected。状态只会由“Pending→Fulfilled”或者“Pending→Rejected”,且状态改变就不会再变
/*Promise对象是由一个构造函数生成实例,接受函数为参数
   函数的参数为resolve和reject。这两者,也是函数*/
   
var promise = new Promise ( function(resolve , reject){
    
    /*一些异步操作*/
    
    if/*异步操作成功*/){
        //当调用resolve函数的时候,Promise对象状态由,Pending → Fulfilled
        //将value值进行传递(一般是异步操作成功后的结果)
        resolve(value)
    }  
    else {
        //当调用reject函数的时候,Promise对象状态由,Pending → Rejected
        //将error值进行传递
        reject(error)
    }    
})    

总体上来说,Promise对象,更像是一个事件的容器,但Promise对象状态的改变并不受事件的完成而完成,而是由参数函数中的 resolve 和 reject 函数来指定它什么时候改变状态。

比如下面代码:

var promise = new Promise ( function(resolve , reject){

    let i = 0//标记事件已完成,传字符串resolved值给.then()处理
    resolve(i)
i += 1 }) .then( //then方法是指,当Promise状态由Pending改变为Resolved时,立即调用 (value) = > { console.log(value) } )

---------------------------------------------------------------
最后输出:
0

then()方法下面会继续讲,问题来了,上面代码“ i += 1”是否会运行呢?再看

var promise = new Promise ( function(resolve , reject){

    resolve()
    console.log('A')
    setTimeout(() => { console.log('B') }, 3000)

}) .then(() = > { console.log('Resolved') })
---------------------------------------------------------------
先后输出:
A
Resolved
B   //3000ms后输出B

Promise对象在状态改变后,内部的代码还是会运行。当内部同步任务全部执行完成后,再调用then()方法。因此前两行最先输出的是‘A’和‘Resolved’,由于B是一个异步事件,所以在3000ms后被调用输出。

如果想在状态改变后直接结束,不执行之后的语句,最好不要将异步操作放在状态改变语句之后!当然也可以这样:

var promise = new Promise ( function(resolve , reject){
    //在前面加上return
    return resolve()

    console.log('A')
    setTimeout(() => { console.log('B') }, 3000)

}) .then(() = > { console.log('Resolved') })
---------------------------------------------------------------
最后只输出:
Resolved

原型方法 —— then()

  • 该方法是定义在Promise对象原型上的方法,即Promise.prototype.then()
  • 且then()方法返回一个新Promise实例

顾名思义,Promise实例状态改变后,要做什么。该方法为其添加了回调函数。Promise实例有两种状态,自然也提供了两种回调(Resolved 和 Rejected)

上面已经简单涉及了该方法,这里整理一下:

var promise = new Promise ( function(resolve , reject){
    //做些什么...
    if/*异步操作成功*/){ resolve(value) }  
    else {  reject(error) }    
}) .then( 
    //then方法接受两个回调函数为参数,以下

    //第一个Promise实例变为Resolved状态调用
    //函数中的参数value,接受Promise实例中resolve(value)传递的value值
    (value) => { /*success*/ },

    //(可选)第二个Promise实例变为Rejected状态调用
    ////函数中的参数error,接受Promise实例中reject(error)传递的error值
    (error) = > { /*failure*/ }
)
  • then()的链式调用

上面说了then方法返回一个新的Promise实例,那么就可以promise.then().then().then().then().then().....这样的链式调用了。

var promise = new Promise ( function(resolve , reject){
    resolve(A)   
}) .then( (value) => {  //此处参数 value 接受 resolve(A) 中的传递值 A
    //输出A
    console.log(value)
    return B
}).then( (value) => {  //此处参数 value 接受上一级then()方法中return的值
    //输出B
    console.log(value)
}).then( (value) => {  //上一个then方法无return时
    //输出undefined
    console.log(value)
})
-----------------------------------------------------------------
先后在控制台上输出:
A
B
undefined

若then()方法中传入的不是函数,则在链式调用中,此then()方法会被忽略,值会传入下一个then方法中

var promise = new Promise ( function(resolve , reject){
    resolve(A)   
}) .then(1)  //这个then方法被忽略
  .then( (value) => {console.log(value)}  )
-----------------------------------------------------------------
控制台上输出:
A

 

原型方法 —— catch()

  • Promise对象原型方法,Promise.prototype.catch()
  • 等同于.then( null , reject(error) )
  • catch()方法返回一个Promise对象

一般应用如下

var promise = new Promise ( function(resolve , reject){
    if/*异步操作成功*/){ resolve(value)}  
    else { reject(new Error ('promise'))}    
}) .then( (value)=>{
    if/*异步操作成功*/){ return A }  
    else { throw new Error('error_A') }  
}).then( (value)=>{
    if/*异步操作成功*/){ return B }  
    else { throw new Error('error_B') }  
}).then( (value)=>{
    if/*异步操作成功*/){return C }  
    else { throw new Error('error_C') }  
}).catch( (error)=>{
    /*此处catch捕获以上从Promise对象到任意then方法所抛出的错误*/
    console.log(error) 
    //catch只能捕获被调用之前抛出的错误,之后的错误如'error_D'就无法捕获
}).then( (value)=>{
    //上面的catch返回一个Promise对象因此可以继续调用then方法 
    if/*异步操作成功*/){return D }  
    else { throw new Error('error_D') }  
})

 

静态方法

  • Promise.all()
  • Promise.race()
  • Promise.resolve()
  • Promise.reject()
Promise.all()

将多个Promise实例包装,并且返回一个新的Promise实例

当包装中所有的Promise状态都变为Resolved时,返回结果数组,数组中返回值的顺序安装包装的数据排列

Promise.all([
   promise_A,
   promise_B,
   promise_C 
]).then(result=>{
  console.log(result)
})
---------------------------
//当promise_A,promise_B,promise_C状态都为Resolved时,result输出一个结果数组:
[result_A,result_B,resultC]

当Promise集合中有一个Promise最终状态为Rejected,就会被Promise.all()的catch方法进行捕获

Promise.all([
      new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('A')
          reject(new Error('AAAAAAAAAAA'))
        }, 5000)
      }),
      new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('B')
          reject(new Error('BBBBBBBBBBB'))
        }, 2000)
      }).catch(e => {
        return e
      })
    ]).then(result => {
      console.log(result)
    }).catch(e => {
      console.log(e)
    })
  }

----------------------------------------------
控制台先后输出:
B            //2s后输出B
A            //5s后输出A
AAAAAAAAAAA            //A输出后立即输出错误'AAAAAAAAAAA'

 上面代码中为什么Promise. all最后捕获的是错误'AAAAAAAAAAA'而不是‘BBBBBBBBBBB’。因为在第二个Promise实例中,2秒后虽然状态变为Rejected并且抛出了Error,但是被自身之后的catch方法捕获了该错误且return。之前已经知道,Promise之后的then和catch方法其实返回的是一个新的Promise实例,若方法中没有抛出新的错误,其后续的状态就会变为Resolved。而第一个实例抛出错误后,并未被后续方法捕获,最后状态为Rejected,错误最终被外层Promise. all方法的后续catch所捕获,最后输出'AAAAAAAAAAA'。

Promis.race()

与上面方法一样,同样将多个Promise实例包装成一个新的Promise实例。

Promise.race([P1,P2,P3])
    .then( value => { /*do something*/ } )
    .catch(e => { /*do something*/ })

Promise实例组中,P1、P2、P3谁的状态先发生变化(Resolved 或 Rejected),Promise.race()状态也发生改变,P1(or P2 or P3)的返回值传递给Promise.race()回调函数。

Promise.resolve()

将一个对象转为一个Promise对象,以下几种情况

let p = new Promise( (resolve,reject) => { resolve(1)} )
//传入Promise对象p,返回还是p
Promise.resolve(p)

//传入一个非thenable对象(thenable对象,就是一个对象具有then方法,下面会说明),或者非对象
Promise.resolve('_JayKoo')
--------------------------------------
//上面代码等同于
new Promise( (resolve,reject) =>{
    resolve('_JayKoo');
})

//thenable对象,具有then方法的对象
//then方法满足以下格式
let obj = {
    then(res , rej){     //then函数,参数满足Promise回调函数中的参数格式。then函数,相当于,Promise构造函数中的回调函数格式。
        if(/*Resolved*/){ res(value) }
        else { rej(error) }
    }
}

//将obj转为Promise对象,且立即调用then方法
Promise.resolve( obj )
---------------------------------------------------------------------------
//以上代码的效果等同于立即执行了
new Promise( (res, rej) => {
    /*obj对象中的操作*/
    if(/*Resolved*/){ res(value) }
    else { rej(error) }
})

//不带参数,立即生成一个Promise对象
//Promise.resolve()方法的执行,是在本轮注册的所有同步脚本事件的结束时(非异步)
let p = Promise.resolve()
Promise.reject()

Promise.reject()同样返回Promise对象.。

在Promise.resolve()中,传入的参数由thenable对象和非thenable对象两种情况,且之后的参数调用情况也不同。

但在Promise.reject()中,所有传参都会被当做Error抛出。

let p = Promise.reject(thenable)
--------------------------------------
//等同于
let p = new Promise( (resolve,reject) => {
    //即使是个thenable对象,也会原封不动地将这个对象当做错误信息抛出
    reject(thenable)
})
--------------------------------------
p.catch( e => {
   console.log( e === thenable) 
})
//true

 

转载于:https://www.cnblogs.com/jaykoo/p/10007910.html

以下是对提供的参考资料的总结,按照要求结构化多个要点分条输出: 4G/5G无线网络优化与网规案例分析: NSA站点下终端掉4G问题:部分用户反馈NSA终端频繁掉4G,主要因终端主动发起SCGfail导致。分析显示,在信号较好的环境下,终端可能因节能、过热保护等原因主动释放连接。解决方案建议终端侧进行分析处理,尝试关闭节电开关等。 RSSI算法识别天馈遮挡:通过计算RSSI平均值及差值识别天馈遮挡,差值大于3dB则认定有遮挡。不同设备分组规则不同,如64T和32T。此方法可有效帮助现场人员识别因环境变化引起的网络问题。 5G 160M组网小区CA不生效:某5G站点开启100M+60M CA功能后,测试发现UE无法正常使用CA功能。问题原因在于CA频点集标识配置错误,修正后测试正常。 5G网络优化与策略: CCE映射方式优化:针对诺基亚站点覆盖农村区域,通过优化CCE资源映射方式(交织、非交织),提升RRC连接建立成功率和无线接通率。非交织方式相比交织方式有显著提升。 5G AAU两扇区组网:与三扇区组网相比,AAU两扇区组网在RSRP、SINR、下载速率和上传速率上表现不同,需根据具体场景选择适合的组网方式。 5G语音解决方案:包括沿用4G语音解决方案、EPS Fallback方案和VoNR方案。不同方案适用于不同的5G组网策略,如NSA和SA,并影响语音连续性和网络覆盖。 4G网络优化与资源利用: 4G室分设备利旧:面对4G网络投资压减与资源需求矛盾,提出利旧多维度调优策略,包括资源整合、统筹调配既有资源,以满足新增需求和提质增效。 宏站RRU设备1托N射灯:针对5G深度覆盖需求,研究使用宏站AAU结合1托N射灯方案,快速便捷地开通5G站点,提升深度覆盖能力。 基站与流程管理: 爱立信LTE基站邻区添加流程:未提供具体内容,但通常涉及邻区规划、参数配置、测试验证等步骤,以确保基站间顺畅切换和覆盖连续性。 网络规划与策略: 新高铁跨海大桥覆盖方案试点:虽未提供详细内容,但可推测涉及高铁跨海大桥区域的4G/5G网络覆盖规划,需考虑信号穿透、移动性管理、网络容量等因素。 总结: 提供的参考资料涵盖了4G/5G无线网络优化、网规案例分析、网络优化策略、资源利用、基站管理等多个方面。 通过具体案例分析,展示了无线网络优化中的常见问题及解决方案,如NSA终端掉4G、RSSI识别天馈遮挡、CA不生效等。 强调了5G网络优化与策略的重要性,包括CCE映射方式优化、5G语音解决方案、AAU扇区组网选择等。 提出了4G网络优化与资源利用的策略,如室分设备利旧、宏站RRU设备1托N射灯等。 基站与流程管理方面,提到了爱立信LTE基站邻区添加流程,但未给出具体细节。 新高铁跨海大桥覆盖方案试点展示了特殊场景下的网络规划需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值