js-Promise基础

js-Promise基础(第三周)


Promise含义

promise意思为允诺、许诺、承诺
在js中为了解决编写代码中的地狱回调,而封装的一个类,实现了同步编程风格来实现异步功能,其本质还是各种回调,它先有社区提出和实现,现在ES6也将promise吸进了,提供了原生的Promise了


Promise简单描述

promise表示一个异步操作的状态,和返回结果,promise有三种状态分别为pending(进行中)、resolved(已完成,又称fulfilled)、rejected(失败);
当promise状态由pending转变为resolved或者rejected时,会相应的执行各自的方法,并且状态一点改变,就不会再次改变,这个可能就是Promise(承诺)这个名字的由来;


生成Promise对象

一般使用两种方法:

  • 第一,直接new一个promise对象
    let promise = new Promise(function(resolve,reject){
        //异步操作的代码
        if(){       //判断是否成功
            resolve(value)//成功后执行代码,值可以再promise.then(value)取出
        }else{
            reject(err)//捕获错误
        }
    })

  • 第二,在函数中用return 返回promise对象,可以传参
    function promise(abc){
        return new Promise(function(resolve,reject){
            //异步操作的代码
        if(){       //判断是否成功
            resolve(value)//成功后执行代码,值可以再promise.then(value)取出
        }else{
            reject(err)//捕获错误
        }
        })
    }

  • promise三种状态
function promise (abc){
   return new Promise(function(resolve,reject){
   
       if(abc){
           setTimeout(() => {  
           resolve("resolve");     //延时100ms后执行resolve
           }, 100);
           
       }else{
           setTimeout(() => {
           reject("reject");     //延时100ms后执行reject
           }, 100);
       }

   })
}
let promise1 = promise(true);//能够执行resolve的promise对象
let promise2 = promise(false);//能够执行reject的promise对象
console.log(promise1);      // 初始状态promise1
console.log(promise2);      // 初始状态promise2
setTimeout(() => {
console.log(promise1);      //延时200ms后的promise1
}, 200);
setTimeout(() => {
console.log(promise2);      //延时200ms后的promise2
}, 200);

结果:


image.png

then()和catch()

then方法是promise对象的方法,可以分别指定resolved状态和rejected状态的回调函数。then方法可以接收两个回调函数作为参数。以一个参数是promise对象状态为resolved是调用的,第二个参数是promise对象状态为rejected时调用,第二个可数是可以选参数。
catch方法在作用是捕获Promise的错误,与then方法的rejected回调作用几乎一致,但是由于Promise的抛错具有冒泡性质,能够不断传递,这样就能够在下一个catch()中统一处理这些错误。同时catch()也能够捕获then()中抛出的错误,所以建议不要使用then()的rejected回调,而是统一使用catch()来处理错误

function promise(abc){
    return new Promise(function(resolve,reject){
        if(abc){
            resolve("这是resolve方法");
        }else{
            throw err= new Error("reject方法执行")//自定义错误
            reject(err)
        }
    })
}
promise(true).then(function(data){
    console.log(data);      //输出 这是resolve方法
},function(err){
    console.log(err);       //不执行
})
promise(false).then(function(data){
    console.log(data);      //不执行
},function(err){
    console.log(err);       //输出 Error:reject方法执行
})
promise(true).then(function(data){//建议写法
    console.log(data);       //输出 这是resolve方法
}).catch(function(err){
    console.log(err);       //不执行
})
promise(false).then(function(data){//建议写法
    console.log(data);      //不执行
}).catch(function(err){
    console.log(err);        //输出 这是resolve方法
})

结果:


image.png

使用

场景回顾看原帖

我今年18岁,准备找个女朋友,有三个人选(姑娘A、B、C),我表白之后姑娘都会过一段时间给我回复;我最喜欢A姑娘,不过我不知A姑娘是不是也喜欢我,表白成功率为0.4,我次之喜欢B姑娘,表白成功率为0.5,我知道姑娘C很喜欢我,表白成率为1,那么问题来了,谁会成为我最终的女票呢?

新场景:最终姑娘A答应我的表白请求,准备登记结婚,结婚领证是需要各自的身份证号,才能领取

场景模拟:用一个数组来收集两个人的身份证号,收集到两个身份证号是将这个数组通过一个方法装换成结婚证
普通回调:

let info = []
function myId(fn){
    fn(1024)
}
function amieId(fn){
    fn(1314520)
}
function writeId(id,callback){
    info.push(id)
    console.log(info)
    if(callback){
        callback()
    }
}
// 开始调用 如果比这再多几层,就不容易看懂了
myId(function(my_Id){
    console.log(`我的身份证号:${my_Id}`)
    writeId(my_Id, function(){
        amieId(function(amie_Id){
            console.log(`姑娘A的身份证号:${amie_Id}`)
            writeId(amie_Id,function(){
                console.log(`生成了结婚证,结婚证号为:${info}`)
            });
         
        })
    })
})

promise方式实现:

let info = []
function myId(id){
   return new Promise(function(resolve,reject){
       if(id){
           resolve(id);
       }else{
           reject(Error);
       }
   })
   
}
function amieId(id){
   return new Promise(function(resolve,reject){
       if(id){
           resolve(id);
       }else{
           reject(Error);
       }
   })
}
function writeId(id){
   return new Promise(function(resolve,reject){
       if(id){
           info.push(id);
           console.log(info);
           
           resolve(id);
           return;
       }else{
           reject(Error);
       }

   })
}
myId(1024).then(function(data){
           console.log(`我的身份证号:${data}`);
          return writeId(data);
           })
         .then(function(){
          return amieId(1314520)
         }
         )
         .then(function(data){
           console.log(`姑娘A的身份证号:${data}`);
          return writeId(data);
           })
         .then(function(){
           console.log(`生成了结婚证,结婚证号为:${info}`)
         })

两种方式结果都是这样的:


image.png

两个在机构上显然promise的这种.then().then().then()……
比会回调function(function(function(){}){}){}……
便于阅读和管理;
之所以Promise对象可以实现链式用法,是因为promise.then()会返回一个新的Promise对象,让前一个Promise对象的终值在then方法中生成一个新的Promise对象,以此类推……


Promise其他方法

Promise.resolve()和Promise.reject()

用来将一个现有的对象包装成Promise对象:
Promise.resolve()包装不同的对象返回的Promise对象会不同:

let a = Promise.resolve();
let b = Promise.resolve("常量");
let c = Promise.resolve({
    name:"发挥不广泛",
    age:18
})
let d = Promise.resolve(b);
let e = Promise.resolve({
    name:"发挥不广泛",
    age:18,
    then:function(resolve,reject){
        console.log(this);
        resolve(this.age);
    }
});
console.log(b===d);      //true
console.log(a);         //不带参数的
console.log(b);         //带一个常量参数
console.log(c);         //带一个没有then方法的对象为参数
console.log(d);         //带一个Promise对象为参数
console.log(e);         //带一个有then方法的对象为参数
setTimeout(() => {      //1000ms后看e状态
    console.log(e);
}, 1000);

结果:


image.png

没有参数:resolved状态的Promise对象
参数是Promise:原样返回
参数带有then方法:转换为Promise后立即执行then方法
参数不带then方法、不是对象或没有参数:返回resolved状态的

Promise.reject()会直接返回rejected状态的Promise

Promise.all()

参数为Promise对象数组,如果有不是Promise的对象,将会先通过上面的Promise.resolve()方法转换

let promise = Promise.all( [p1, p2, p3] )
promise.then(
    ...
).catch(
    ...
)

当p1、p2、p3的状态都变成resolved时,promise才会变成resolved,并调用then()的已完成回调,但只要有一个变成rejected状态,promise就会立刻变成rejected状态

Promise.race()

let promise = Promise.race( [p1, p2, p3] )
promise.then(
    ...
).catch(
    ...
)

“竞速”方法,参数与Promise.all()相同,不同的是,参数中的p1、p2、p3只要有一个改变状态,promise就会立刻变成相同的状态并执行对于的回调

Promise.done() 和 Promise. finally()

Promise.done方法的用法类似 then方法,可以提供resolved和rejected方法,也可以不提供任何参数,它的主要作用是在回调链的尾端捕捉前面没有被 catch方法 捕捉到的错误

Promise. finally() 接受一个方法作为参数,这个方法不管promise最终的状态是怎样,都一定会被执行,不用他相当于在resolve方法和reject方法中都写一遍

<完>
20180810


发挥不广泛微信公众号

发挥不广泛

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容

  • Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函...
    neromous阅读 8,703评论 1 56
  • title: promise总结 总结在前 前言 下文类似 Promise#then、Promise#resolv...
    JyLie阅读 12,234评论 1 21
  • 一、Promise的含义 Promise在JavaScript语言中早有实现,ES6将其写进了语言标准,统一了用法...
    Alex灌汤猫阅读 820评论 0 2
  • Promise对象是一种解决异步问题的方法,还有的解决方案是asyns 和 await (es7) 这么是目前的终...
    站在大神的肩膀上看世界阅读 1,261评论 0 6
  • 盛夏的夜里,等一颗天空最亮的星星.
    洛阳风轻阅读 131评论 0 1