Promise 实践

作者:何方舟

promise已经是成为我们解决回调炼狱的常用方案,而且已经得到官方标准支持,如果你刚刚开始使用Promise,本文将帮助你了解几个常见的几个Promise的使用场景

使用Promise可以让程序的可读性变得更好。如下面这样的代码:

var p = Promise.resolve();
      p.then(getUserInfo)
       .then(getGroupInfo)
       .then(getTaskInfo)
       ...

function getUserInfo(){
    
   console.log('getUserInfo start');
   return new Promise((resolve,reject)=>{
       setTimeout(()=>{
            var userInfo = {
                name  'adamchuan'
            };
            resolve(userinfo);
            console.log('getUserInfo end');
       },1000);
   });
}

function getGroupInfo(userinfo){
   console.log('getGroupInfo start');
   return new Promise((resolve,reject)=>{
       setTimeout(()=>{
            console.log('4');
            var groupInfo = {
                name : 'jdc'
            }
            console.log('getGroupInfo end');
            resolve(groupInfo,userinfo);
       },1000);
   });
}

function getTaskInfo(groupInfo,userinfo){
   console.log('getTaskInfo start');
   return new Promise((resolve,reject)=>{
       setTimeout(()=>{
        var taskInfo = {
            name : 'rebuild'
        };
        console.log('getTaskInfo end');
        resolve();
       },1000);
   });
}

/* 输出结果 
 getUserInfo start
 getUserInfo end
 getGroupInfo start
 getGroupInfo end
 getTaskInfo start
 getTaskInfo end
*/

如上面代码所示,我们可以很清楚的理解到程序执行的顺序是

  1. 得到userinfo
  2. 得到groupinfo
  3. 得到taskinfo

这样的代码在许多Promise示例中都可见,但这里有一点需要特别注意一下,

每次调用then都会返回一个新的Promise,如果then中的申明的方法没有返回一个Promise,那么会默认返回一个新的

处于fulfilled的Promise,之后添加的then中的方法都会立即执行,

如下面代码所示,如果在上面的代码中没有返回一个promise,输出的结果就变成 1 3 5 2 4 6了。

当要在使用链式Promise时,请在then传入的方法中返回一个新的Promise。

var p = Promise.resolve();
      p.then(getUserInfo)
       .then(getGroupInfo)
       .then(getTaskInfo)
       ...

function getUserInfo(){
   console.log('1');
   new Promise((resolve,reject)=>{
       setTimeout(()=>{
        console.log('2');
        resolve();
       },1000);
   });
}

function getGroupInfo(){
   console.log('3');
   new Promise((resolve,reject)=>{
       setTimeout(()=>{
        console.log('4');
        resolve();
       },1000);
   });
}

function getTaskInfo(){
   console.log('5');
   new Promise((resolve,reject)=>{
       setTimeout(()=>{
        console.log('6');
        resolve();
       },1000);
   });
}

/* 输出结果 
 getUserInfo start
 getGroupInfo start
 getTaskInfo start
 getUserInfo end
 getGroupInfo end
 getTaskInfo end
*/

另外一个需要注意的是,resolve传递给下个then方法的值只能有一个,上面 getTaskInfo方法中是无法获取到userInfo的值,所以如果有多个值需要放在一个数据集合(Array,Object,Map,Set)中传入下个方法)。

function getTaskInfo(groupInfo,userInfo){ /* userInfo为undefined */
   console.log(groupInfo); // { name : 'jdc'}
   console.log(userInfo);  // undefined
}

原生API函数的Promise化

大部分原生的API函数并不支持Promise,还是基于回调来使用的,所以需要把一些方法Promise化,类似trunk化。

下面一个例子把原生中的定时器setTimeout ,进行Promise化。

function timer(fn,time){
    return function(){
        return new Promise( (resolve,reject)=>{
            setTimeout(function(){
                fn();
                resolve();
            },time);
        });
    }
}
Promise.resolve()
    .then(
        timer(function () {
            console.log('1')
        }, 1000)
    )
    .then(() => {
        console.log('2');
    });

Promise化本质上都属于一种curry化。curry化是指,把需要传递多参数的函数生成一个新的函数,如上代码 先通过执行 timer得到一个新的函数,该函数会返回一个Promise,这样就完成了Promise化。

 timer(function () {
    console.log('1')
 }, 1000) 

原文链接:http://ivweb.io/topic/58204de262a899565c1c8914

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C语言及其他语言

[每日一题]自定义函数与宏定义

前面,我们既一起研究了自定义函数的题,有看了宏定义的题,下面这题刚好就是要用自定义函数和宏定义解题的,帮大家巩固知识点 题目描述 分别用函数和带参的宏,从三个...

2825
来自专栏前端那些事

基础 - 从模板语法数据绑定、指令到计算属性总结

写在前面 今年前端届比较有意思,从大漠穷秋发表文章比较angular和vue,继而致歉vue作者、社区,从谷歌辞去Angular Developer PM in...

2749
来自专栏猿人谷

为什么使用抽象类?有什么好处?

最简单的说法也是最重要的理由:接口和实现分离 老是在想为什么要引用抽象类,一般类不就够用了吗。一般类里定义的方法,子类也可以覆盖,没必要定义成抽象的啊。 看了下...

1789
来自专栏web前端教室

web前端零基础课-0907*凯政-学习笔记

2.1 - Js数据类型,5中基本数据类型( String, Number, Boolean, Undefined, Null ),一种复杂数据...

802
来自专栏编程

三撩Python

我不求深刻,只求简单。 --三毛 1、起手 我呢,一个咖啡师,咖啡使我忙碌与充实。 每天端起咖啡,香气弥漫,轻轻一口,就在那一刹那,没有时间,没有空间,没有纷纷...

1779
来自专栏菜鸟前端工程师

JavaScript学习笔记018-面向对象编程思维0构造函数0Class

922
来自专栏Golang语言社区

厚土Go学习笔记 | 10. 常量 与 数值常量

量的定义与变量类似,只是需要使用 const 关键字。 常量可以是字符、字符串、布尔型、数字型的值。 需要注意的是,常量不可以使用 := 语法定义。 packa...

3428
来自专栏前端小栈

javaScript循环总结(for,for-in,for-of,forEach,map,filter,every,reduce,reduceRight)

循环是每个语言都必不可少的方法,javaScript也一样,随着javaScript的发展,我们用于循环的方法也在不断改进,也越来越精简,但是用好循环却不是那...

853
来自专栏LEo的网络日志

冒泡排序

3466
来自专栏前端说吧

jade(pug)学习笔记(待填充.......)

3466

扫码关注云+社区