关于Promises

一、名字

        promise(首字母小写):一个对象,Promise的实例对象

        Promise(首字母大写,单数):Prmoise构造函数

        Promises(首字母大写,复数):指代Promise规范

二、Promises/A规范和ES6 Prmoises规范

        Prmoises规范有几次升级,目前来说,Promises/A是最新的民间规范。ES6 Prmoises是最新的官方规范。

三、Promises的意义

        1、解决回调金字塔的问题(回调圣诞树,回调地狱)

        2、可以同时管理成功回调和失败回调

四、所谓“承诺”

        Promises这个单词翻译为“承诺”。程序的世界里,理解为:我承诺给你完成这些代码的执行。new有一个Prmoise实例,就是js引擎给你一个承诺。

        执行承诺,就会有成功或者失败,只是概率问题。

        在程序世界里,一个承诺也只会有三种状态:“未解决(pendding)”、“成功的(resolve)”、“失败的(reject)”。

五、Promise构造函数的能力

        本质:prmoises写法的本质就是把 异步写法撸成同步写法。

        怎么做到的呢?

        就是安排一下代码执行的先后顺序:Promise构造函数有特殊的功能,传入Prmoise构造函数的函数参数会优先第一执行,也就是说,只要new一个Prmoise,那么Promise构造函数的函数参数是最高优先级执行的,一直到new一个Promise对象实例后面的then()代码才会执行。链条行的每一个then()都会等到前面promise有了结果才会执行。

        Promise是一个构造函数,用来生成prmoise实例。

        Promise构造函数接受一个函数作为参数,这个函数的两个参数分别是:resolve和reject。他们是两个函数,有js引擎提供(自带的。

        resolve函数的作用:将promise对象的状态从“未完成”变成“成功”。在异步操作成功时调用,并将异步的结果作为参数传递出去。

        reject函数的通:将promise对象的状态从“未完成”变成“失败”。在异步操作失败的时候调用,并将错误作为参数传递出去。

        promise对象生成以后,可以用then()方法分别制定resolve状态和reject状态的回到函数

六、撸代码

        传统的回调地狱写法:

                firstAsync(function(data){

                    //拿到data的数据 处理业务逻辑 do something

                    secondAsync(function(data2){

                         //拿到data2的数据 处理业务逻辑 do something

                        thirdAsync(function(data3){

                                //拿到data3的数据 处理业务逻辑 do something

                        })

                    })

                })

       哈哈哈,像不像一个金字塔。可读性和维护性都比较差

        引入Promise的写法:

        firstAsync().then(function(data){

                //拿到data的数据 处理业务逻辑 do something

                return secondAsync() //继续处理第二个异步

        }).then(function(data2){

            //拿到data2的数据 处理业务逻辑 do something

            return thirdAsync() //继续处理第二个异步

        }).then(function(data3){

                //拿到data3的数据 处理业务逻辑 do something

        })

        通过then的链式写法,把回调按照顺序串联起来。

        更直接的例子:有做饭、吃饭、洗碗筷这三个异步的操作,他们是层层依赖,下一步的操作依赖上一步操作的结果

        =》

        (1)下面通过样例作为演示,我们定义做饭、吃饭、洗碗(cook、eat、wash)这三个方法,它们是层层依赖的关系,下一步的的操作需要使用上一部操作的结果。(这里使用 setTimeout 模拟异步操作)

                //做饭    

function cook(){

console.log("开始做饭");

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

setTimeout(function(){

console.log("做饭完毕")

resolve("老北京炸酱面")

},1000)

})

return p;

}

//吃饭

function eat(data){

console.log("开始吃饭:"+data)

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

setTimeout(function(){

console.log("吃饱啦")

resolve("筷子盘子碗")

},2000)

})

return p

}

//洗碗筷

function wash(data){

console.log("开始洗碗筷:"+data)

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

setTimeout(function(){

console.log("洗好啦")

resolve("干净的碗筷")

},2000)

})

return p

}


(2)使用 then 链式调用这三个方法:

cook()

.then(function(data){

    returneat(data);

})

.then(function(data){

    returnwash(data);

})

.then(function(data){

    console.log(data);

});


好了,看运行的结果:

Promises.html:14 开始做饭

Promises.html:17 做饭完毕

Promises.html:26 开始吃饭:老北京炸酱面

Promises.html:29 吃饱啦

Promises.html:39 开始洗碗筷:筷子盘子碗

Promises.html:42 洗好啦

Promises.html:54 干净的碗筷


七、all

        Promises的all方法,拓展了异步操作的能力,即在所有指定的异步操作都结束后才运行回调。

        直接上代码:

        //切菜

function cut(){

console.log("开始切菜:青菜")

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

setTimeout(function(){

console.log("切菜完毕")

resolve("切好的青菜")

},1000)

})

return p

}

//烧水

function boil(){

console.log("开始烧水")

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

setTimeout(function(){

console.log("烧水完毕")

resolve("烧好的水")

},2000)

})

return p

}

//all then把操作逻辑串起来

Promise.all([cut(),boil()]).then(function(data){

console.log("准备工作完毕")

console.log(data)

})


结果:

开始切菜:青菜

Promises.html:72 开始烧水

Promises.html:64 切菜完毕

Promises.html:76 烧水完毕

Promises.html:84 准备工作完毕

Promises.html:85 ["切好的青菜", "烧好的水"]

八、Promises的race方法:和all类似,是异步能力的拓展,区别是all是所有异步操作都结束才能执行回调, race 的话只要有一个异步操作执行完毕,就立刻执行 then 回调。

注意:其它没有执行完毕的异步操作仍然会继续执行,而不是停止。

上面的切菜烧水操作定义好以后:

Promise.race([cut(),boil()]).then(function(data){

console.log("至少有一个工作准备好了")

console.log(data)

})


结果注意顺序:

开始切菜:青菜

Promises.html:72 开始烧水

Promises.html:64 切菜完毕

Promises.html:89 至少有一个工作准备好了

Promises.html:90 切好的青菜

Promises.html:76 烧水完毕

注意,race的应用场景很多,比如同时向后台发起多个ajax的异步请求,并且都有超时时间设置。

比如:

//请求某个图片资源

function requestImg(){

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

    var img = new Image();

    img.onload = function(){

      resolve(img);

    }

    img.src = 'xxxxxx';

    });

    return p;

}

//延时函数,用于给请求计时

function timeout(){

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

        setTimeout(function(){

            reject('图片请求超时');

        }, 5000);

    });

    return p;

}

Promise

.race([requestImg(), timeout()])

.then(function(results){

    console.log(results);

})

.catch(function(reason){

    console.log(reason);

});

上面代码 requestImg 函数异步请求一张图片,timeout 函数是一个延时 5 秒的异步操作。我们将它们一起放在 race 中赛跑。

如果 5 秒内图片请求成功那么便进入 then 方法,执行正常的流程。

如果 5 秒钟图片还未成功返回,那么则进入 catch,报“图片请求超时”的信息。

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

推荐阅读更多精彩内容

  • Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函...
    neromous阅读 8,707评论 1 56
  • 本文适用的读者 本文写给有一定Promise使用经验的人,如果你还没有使用过Promise,这篇文章可能不适合你,...
    HZ充电大喵阅读 7,312评论 6 19
  • 一、Promise的含义 Promise在JavaScript语言中早有实现,ES6将其写进了语言标准,统一了用法...
    Alex灌汤猫阅读 827评论 0 2
  • 欢迎阅读专门探索 JavaScript 及其构建组件的系列文章的第四章。 在识别和描述核心元素的过程中,我们还分享...
    OSC开源社区阅读 1,154评论 1 10
  • 城市的上空密密麻麻 广阔的网眼里筛入空气和水 人们披着斑斓的长衣服 用舞蹈代替行走 地面并不存在 无底的深渊奇花蔓...
    孟小繁阅读 196评论 0 0