一、Promise是什么?

在JavaScript中,所有的代码都是单线程执行,所以javaScript的所有网络操作(“GET”/"POST"/"PUT"/"DELETE")以及浏览器事件("onload"/"onclick"/...)都是异步执行,异步执行的函数可以通过回调函数实现。

关于回调函数在知乎看到过一个很有意思的回答:

你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。

用setTimeout来实现异步操作

function callback (){
console.log("I'm a callback")
}
console.log("before setTimeout");
setTimeout (callback,2000); //两秒钟后执行callback
console.log("after setTimeout") //观察Chrome 控制台输出
//before setTimeout
//after setTimeout
//2秒钟后
//I'm a callback

我们知道,AJAX是典型的异步操作引擎,但是代码量大也不利于复用,最好能写成链式操作,比如:

var ajax = ajaxGet('http://...');
ajax.ifSuccess(success).ifFail(fail);

不管处理结果如何,先执行AJAX逻辑,然后根据结果成功与否,在将来的某个时刻调用ifSuccess()或者ifFail()函数。

我们就把这种“承诺”在将来执行的对象,称为Promise对象。Promise对象有两大特点:

  1. 对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:
  • pending(进行中)
  • fulfilled(已成功)
  • rejected(已失败)

只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

二、Promise的基本用法

const promise = new Promise(function(resolve,reject){
if(/*异步操作成功*/){
resolve(value)
}else{
reject(error)
}
})

上面的代码创建了一个promise实例,Promise构造函数接受一个函数作为参数,该函数又有两个JavaScript引擎部署的两个参数——resolve和reject,resolve会把promise从pending编程resolved,reject会把pending变为rejected。

promise指定了then()和catch()方法,then()方法第一个参数是resolved状态的回调函数,第二个参数(一般不使用)是rejected状态的回调函数。catch()方法是then(null,rejection)或者then(undefined,rejection)的别名,用于指定发生错误时的回调函数。

三、用promise对象实现AJAX操作

前面我们提到了,AJAX操作可以用promise对象进行简化,如下:

const getJSON = function(url) {  //封装XMLHttpRequest
  const promise = new Promise(function(resolve, reject){
const handler = function() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
const client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send(); }); return promise; //返回promise对象
}; getJSON("/posts.json")
.then(function(json) {
console.log('Contents: ' + json);
})
.catch(function(error) {
console.error('Contents: ' + error);
});

参考文献:廖雪峰的官方网站https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/0014345008539155e93fc16046d4bb7854943814c4f9dc2000

阮一峰:http://es6.ruanyifeng.com/#docs/promise

PS:最近一直在学vue框架,涉及到promise和AJAX以及node.js操作比较多,特别回顾了一下,把promise原理和特性梳理清楚,文章不足之处还请谅解

【学习笔记】浅析Promise函数的更多相关文章

  1. JavaScript:学习笔记(9)——Promise对象

    JavaScript:学习笔记(9)——Promise对象 引入Promise Primose是异步编程的一种解决方案,比传统的解决方案回调函数和事件更加合理和强大.如下面为基于回调函数的Ajax操作 ...

  2. IOS学习笔记07---C语言函数-printf函数

    IOS学习笔记07---C语言函数-printf函数 0 7.C语言5-printf函数 ------------------------- ----------------------------- ...

  3. IOS学习笔记06---C语言函数

    IOS学习笔记06---C语言函数 --------------------------------------------  qq交流群:创梦技术交流群:251572072              ...

  4. Typescript 学习笔记三:函数

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  5. ES6学习笔记<三> 生成器函数与yield

    为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...

  6. OpenCV 学习笔记03 findContours函数

    opencv-python   4.0.1 1 函数释义 词义:发现轮廓! 从二进制图像中查找轮廓(Finds contours in a binary image):轮廓是形状分析和物体检测和识别的 ...

  7. canvas学习笔记、小函数整理

    http://bbs.csdn.net/topics/391493648 canvas实例分享 2016-3-16 http://bbs.csdn.net/topics/390582151 html5 ...

  8. Go语言学习笔记七: 函数

    Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...

  9. JavaScript:学习笔记(5)——箭头函数=>以及实践

    JavaScript:学习笔记(5)——箭头函数=>以及实践 ES6标准新增了一种新的函数:Arrow Function(箭头函数).本文参考的链接如下: MDN箭头函数:https://dev ...

  10. jQuery源代码学习笔记_工具函数_noop/error/now/trim

    jQuery源代码学习笔记_工具函数_noop/error/now/trim jquery提供了一系列的工具函数,用于支持其运行,今天主要分析noop/error/now/trim这4个函数: 1.n ...

随机推荐

  1. FastReport之实现打印固定行数,不足补打空白行的办法

    在设置单据的打印模板的时候,我们有时候会遇到这样的情况:单据的内容很少,打印出来的效果不理想的情况,例如1.单据体与单尾之间有大量的空白: 2.单据体跟单尾连在一起,单尾后面的空白篇幅太大: 以上这两 ...

  2. Android-Java-同步方法-synchronized

    1.方法具有封装性: /** * 1.方法具有封装性: */ public void addMoney(double moneyAsset) { this.moneyAsset += moneyAss ...

  3. codefirst数据迁移技术,在保留数据库数据下实现对模型的修改并映射到数据库

    一前言 这是我的处女作,写的不好的地方还望指出共同讨论.EF的数据访问方式有三种DbFirst,ModelFirst,还有本文要提到的CodeFirst 三者都是以ORM的方式建立.本人之前学习的.n ...

  4. MS SQL的某一数据库成了Single User模式

    数据库恢复失败,原来的数据却变成了 当尝试打开数据库的属性,即出现上面图片异常的信息. 正常来说,是可以打开数据库的属性 此刻,你可以运行SQL语句来解决: USE master; GO ALTER ...

  5. JQuery Mobile - 导航栏选中状态代码

    class="ui-btn-active" 参考: https://wizardforcel.gitbooks.io/w3school-jqmobile/content/8.htm ...

  6. Python 关于 encode与decode 中文乱码问题

    字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(en ...

  7. 防止sql注入的小函数 以及一些小验证

    function test_input($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialch ...

  8. es6 学习小记 扩展运算符 三个点(...)

    参考: es6 扩展运算符 三个点(...) 经常回顾,方能真正掌握. 一.含义 扩展运算符( spread )是三个点(...).它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列. ...

  9. java后端树形菜单使用递归方法

    数据库的设计 使用ssm 实体类 mapper映射文件查询出所有的菜单 使用递归方法

  10. POJ 2591

    #include<iostream> #include<stdio.h> #define MAXN 10000001 using namespace std; int a[MA ...