Promise对象被写进ES6的规范当中,提供的是另外一种更加友好的对于异步编程的解决方案,在这之前大多使用的是回调函数和事件来实现异步编程。

怎么来理解Promise对象呢?对于这个ES6新加入的小伙伴,首先是它一个和其他诸如Array,Date,Math,Global等对象一样的东西,只不过Promise可以作为异步编程的一种解决方案,至于是不是最好的异步编程解决方案,这个以后再讨论。
        正因为是为了解决异步编程,相应的,Promise对象是有状态的,事儿是办好了还是办不好,总要有个状态来标识。Promise对象的状态是通过在执行new Promse()的时候传入的两个参数(函数)的执行来决定的,如下:

 
const promise=new Promise((resolve,reject)=>{
    if(.....)
       resolve(argv1)
    else
       reject(argv2)
})
 
 

上述例子当中,resolve,reject表示的是promise对象可能有的两种状态,分别表示”成功了“和”失败了“,当然还有一种状态是”进行中“,这个在Promise对象中没办法明显表示出来。总结就是:
Promise对象有三种状态:resolved(完成了,可以了),rejected(对不起,报错了),pending(还在酝酿,别着急)这三种状态。
这三种状态怎么来的呢?
就看上述传入到new Promise()中的参数,(第一个参数表示状态已经完成,第二个表示状态已经失败),哪一个函数先执行了,resolve函数先执行,好了,生成的Promise对象的状态就是已经完成;reject函数先执行,欧了,生成的Promise对象的状态就是失败了,其余的状态就是 进行中。
注意:1.Promise对象的状态一旦决定了,就不能改变了
           2.Promise对象的状态转变只能是两种方式:pending——>resolved(进行中---->完成了);pending——>rejected(进行中----->失败了),再无其他可能性

说好的异步编程呢,哪去了?别急,下文就是就是异步的内容了。
光生成一个Promise对象,只是一个前奏。Promise对象prototype链上有两个方法then(),catch();then()方法表示的是“对象都生成了,然后干啥呢”,这一步是异步操作then方法里面有两个函数参数,和生成Promise对象类似,
then()和catch()方法中的参数,就是生成Promsie对象时候,执行resolve和reject方法时传入的参数。
代码如下:

 
then((resolve)=>{
    //do something
    //Promise对象状态为[b]完成了[/b]的时候执行
},(reject)=>{
     //do something
    //Promise对象状态为[b]失败了[/b]的时候执行
})
 
 

但是不推荐以上这种写法,推荐如下写法:

 
 
then((resolve)=>{
    //do something
    //Promise对象状态为[b]完成了[/b]的时候执行
}).catch((reject)=>{
    //do something
    //Promise对象状态为[b]失败了[/b]的时候执行
})
 
 

铺垫了这么多,上面试题:
题目1:

 
console.log(1);
new Promise(function (resolve, reject){
    reject(true);
    window.setTimeout(function (){
        resolve(false);
    }, 0);
}).then(function(){
    console.log(2);
}, function(){
    console.log(3);
});
console.log(4);
 
 

答案是1 4 3,令人揪心,为什么编辑器输出的答案是1 4。。。不知道为什么,
不管咋样,正确答案就是1 4 3。
其中涉及到的知识点有:
1.new Promise 对象的时候,参数函数体内部,先执行了第二个参数(是一个函数),因此生成的Promise对象的状态为是失败了,再无变成其他状态的可能性;
2.在Promise对象生成后,执行的then方法时,由于Promise对象的状态为“失败了”,所以执行then中的第二个参数方法;
3.then方法是异步操作,在输出结果的时候要先等到所有同步操作执行完毕以后再执行,所以,按顺序先执行console.log(1),console.log(4),然后再执行console.log(3)


题目2:

 
new Promise((resolve,reject)=>{
    var bool=true;
    if(bool){
        resolve("yes,good")
    }else{
        reject("no,bad")
    }
}).then((msg)=>{
    console.log("msg:",msg);
    console.log("unknown:",unknown)
}).catch((err)=>{
    console.log("error:",err)
}).then((msg1)=>{
    console.log("msg1:",msg1)
}).then(()=>{
   return "我不是undefined"
).then((msg)=>{
    console.log("msg:",msg);
).then(()=>{
    console.log("到底线了")
})
 
 

答案是:msg: yes,good
             error: ReferenceError: unknown is not defined(…)
             msg1: undefined
             msg: 我不是undefined
             到底线了
其中涉及到的知识点有:
1.then方法中的两个回调函数中的参数是生成Promise对象的时候传入的,所以第一个then方法中的msg的实参是"yes,good";
2.catch会捕捉其之前出现的所有错误,也就是说前面的promise中出现的错误会一直冒泡到后面,直到有catch来接收;
3.then,catch方法执行后会返回一个处理过的Promsie对象,这也是链式写法的基础,至于这个处理后的Promise对象到底是哪个,可以这么理解:
    a.如果then没有返回值,那么返回的是是一个空的Promise对象,由Promise.resolve()或者Promise.reject()直接生成
    b.如果then有返回值data,那么返回的就是Promise.resolve(data)的Promise对象,其等效于new Promise((resolve){resolve(data)}),reject的情况类似,这就解释了第二次打印msg的时
       候是有值的,这就是上面个的then返回的Promise对象的resolve方法 的参数,传递给下面的then方法使用


题目3:

var p1 = new Promise((resolve, reject) => {
    setTimeout(function () {
        reject("出错了")
    }, 1000)
});
var p2 = new Promise((resolve, reject) => {
    resolve(p1)
});
p2.then((msg) => {
    console.log("msg:", msg)
}).catch(() => {
    console.log("出错了")
})
 
 

答案是:出错了
其中涉及到的知识点有:
1.当resolve中的参数是一个Promise对象的时候,要等到该Promise对象的状态确定后(完成了或是失败了)才能进行下一步,而且其状态决定了下一个Promise对象的状态,
  案例中,p2的状态要等到p1的状态确定后才决定,然而p1的状态是 失败了,p2的状态也是失败的,这点要注意。


关于Promise对象,还有其他API可以研究,比如Promise.all和Promise.race等等。
关于异步编程,Generator函数以及ES7的async函数都是更好的实现方案。

写在最后的话
Javascript,越来越多的新特性,结合工作中遇到的问题原生支持了越来越多的属性,越来越强大,对于企业级应用开发更加得心应手。
大前端,上手简单,提升阶段需要的知识结构可以说比Java,c++ 等语言更多,更杂;
只是绘制页面,对于前端来说是很基础的工作,结合工作需要,更多的要考虑组件化,工程化,优化性能,接手后台功能;
已经有不少性能稳定的自动化后端服务平台,不需要后端童鞋来配合,后端模块可以按需随意调用,服务器直接用稳定的云服务,更多的工作交给了前端,体验,用户体验,干掉后端不敢说,后端的工作慢慢在弱化;
前端江湖,各种插件,各种组件库风起云涌,快速迭代,开发效率越来越高,这是不是有点像战国时期百家争鸣,民国时期的百花齐放。
这是前端最好的时代,将来可能是Javascript一统江湖的时代(不是说其他语言不存在了,而是说Javascript一支独大);
胡乱预测,五年后再看这段话。
共勉。

promise知识点汇总的更多相关文章

  1. ECMAScript版本知识点汇总

    ECMAScript版本知识点汇总 ES5 btoa.atob 对参数进行base64格式编码.解码 /** * btoa() * base64编码 * @param {string} str * @ ...

  2. nginx几个知识点汇总

    WHY? 为什么用Nginx而不用LVS? 7点理由足以说明一切:1 .高并发连接: 官方测试能够支撑 5 万并发连接,在实际生产环境中跑到 2 - 3 万并发连接数.?2 .内存消耗少: 在 3 万 ...

  3. python全栈开发 * 10知识点汇总 * 180612

    10 函数进阶 知识点汇总 一.动态参数 形参的第三种1.动态接收位置传参 表达:*args (在参数位置编写 * 表⽰接收任意内容) (1)动态位置参数def eat(*args): print(a ...

  4. 清华大学OS操作系统实验lab1练习知识点汇总

    lab1知识点汇总 还是有很多问题,但是我觉得我需要在查看更多资料后回来再理解,学这个也学了一周了,看了大量的资料...还是它们自己的80386手册和lab的指导手册觉得最准确,现在我就把这部分知识做 ...

  5. c++ 函数知识点汇总

    c++ 函数知识点汇总 swap函数 交换两个数组元素 比如 swap(a[i],a[j]); 就是交换a[i] 和 a[j] 的值 strcpy() 复制一个数组元素的值到另一个数组元素里 strc ...

  6. 前端开发 JavaScript 干货知识点汇总

    很多初学的朋友经常问我,前端JavaScript都需要学习哪些东西呀?哪些是JavaScript的重点知识啊? 其实做前端开发工程师,所有的知识点都是我们学习必备的东西,只有扎实的技术基础才是高薪的关 ...

  7. BBS项目知识点汇总

    目录 bbs项目知识点汇总 一. JavaScript 1 替换头像 2 form表单拿数据 3 form组件error信息渲染 4 添加html代码 5 聚焦操作 二 . html在线编辑器 三 . ...

  8. Java面试知识点汇总

    Java面试知识点汇总 置顶 2019年05月07日 15:36:18 温柔的谢世杰 阅读数 21623 文章标签: 面经java 更多 分类专栏: java 面试 Java面试知识汇总   版权声明 ...

  9. 离散数学 II(最全面的知识点汇总)

    离散数学 II(知识点汇总) 目录 离散数学 II(知识点汇总) 代数系统 代数系统定义 例子 二元运算定义 运算及其性质 二元运算的性质 封闭性 可交换性 可结合性 可分配性 吸收律 等幂性 消去律 ...

随机推荐

  1. Mybatis基础学习(五)—缓存

    一.概述      mybatis提供查询缓存,如果缓存中有数据就不用从数据库中获取,用于减轻数据压力,提高系统性能.           一级缓存是SqlSession级别的缓存.在操作数据库时需要 ...

  2. 《连载 | 物联网框架ServerSuperIO教程》- 18.集成OPC Client,及使用步骤

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  3. 常用JS工具包

    /*********** *时间辅助类 ***********/ var DateHelper = { //得到两个时间的差值(天数) DateDiff: function (startDate, e ...

  4. JavaScript编码解码以及C#中的编码解码

    JS: 编码 解码 escape   unescape encodeURI decodeURI encodeURIComponent decodeURIComponent C#: HttpUtilit ...

  5. iOS标注和适配

    很多项目一开始没有注意美术素材的规范,这在后期会引起混乱.假如有机会做一个新项目(旧项目会有自己的历史问题,一下子很难改过来),建议设计师和程序员一起坐下来.共同设立一套规范,之后共同遵守. 下面说说 ...

  6. mac的终端为什么会显示git:(master),如何取消掉?

    今天在终端误操作,在主目录下执行git init命令,结果杯具了, 总是出现这个提示. 各种搜索解决方案,终于退出了. 方法如下: 删掉.git目录: rm -rf ~/.git

  7. java复习(9)---数据库JDBC

    java写工程当然需要连接数据库.JDBC技术是连接数据库和应用程序的纽带,本节主要说明如何连接数据库. java中提供sql类. package re09; import java.sql.*; p ...

  8. a标签去掉默认样式并自定义样式

    a { text-decoration: none;//去掉下划线 color: inherit; -webkit-user-select: none; -moz-user-select: none; ...

  9. POJ 3294 出现在至少K个字符串中的子串

    在掌握POJ 2774(两个串求最长公共子串)以及对Height数组分组后,本题还是容易想出思路的. 首先用字符集外的不同字符连接所有串,这是为了防止两个后缀在比较时超过某个字符串的分界.二分子串的长 ...

  10. ArrayList 如何完美去除空值

    package sourceCode.ArrayList; import java.util.ArrayList; import java.util.List; public class arrayL ...