从零开始学_JavaScript_系列(48)——Promise(1)基础知识
来源:互联网 发布:软件开发人员薪酬 编辑:程序博客网 时间:2024/06/05 07:59
1、是什么
- 一个十分适合处理异步操作的对象
- 有进行中(pending)、成功(resolved)、失败(rejected)三种状态
- 可以轻松处理成功或失败的情况,代码结构更清爽,操作结果可预期
- 对象的状态不受外界影响,只会根据预先设定的情况执行代码,方便从pending状态切换到resolved或者rejected
- Promise对象在创建后会立即执行,但他的then是异步的(即使状态立刻改变,也要等其他代码执行完毕后才会去执行)
- Promise对象的状态改变是一次性的,改变后值即确定。不会因为任何情况导致状态反复变化
- Promise的状态改变后,会立刻触发其回调函数(执行resolve或者reject)
- Promise对象foo可以作为另外一个Promise对象bar的值,并且在foo和bar的状态都不是pending后,才会执行bar的回调
- Promise对象的then的值是Promise对象,但和最初的Promise不是同一个
- then可以连写,方便连续异步函数的调用
- Promise.all可以轻松处理多个异步操作,在全部完成后才应执行的逻辑
- Promise.race可以轻松处理多个异步操作,但只需要最快的那个异步操作结果的情况
- Promise.resolve和Promise.reject可以轻松将一个变量转为Promise对象并使用
2、基本例子
Promise有几个特点:
- new出来后立刻执行;
- 只执行一次,并且结果发生后,无论之后几次调用then,都只执行那唯一一个结果(resolve或者reject);
- 如果处于pending中,那么执行then时,相当于添加到队列里,pending中不执行,但等结果出来后,会一起执行(而非只执行一个或者不执行);
- resolve或者reject只能接受一个参数,如果要传多个参数的话,请使用数组或者对象的形式;
- resolve和reject里函数不是在声明时执行,而是异步的,在判定promise的状态为非pending状态时执行;
如以下示例:
console.log(new Date);let foo = new Promise(function (resolve, reject) { setTimeout(function () { //获取毫秒的数值 var d = (new Date()).getMilliseconds(); if (d % 2 === 0) { resolve([new Date(), d]); } else { reject([new Date(), d]); } }, 1000);})foo.then(function (arr) { console.log(new Date); console.log("resolve: " + arr[0]);}, function (arr) { console.log("reject: " + arr[0]);})foo.then(function (arr) { console.log(arr[1]); console.log("resolve: " + arr[0]);}, function (arr) { console.log(arr[1]); console.log("reject: " + arr[0]);})//Tue Jul 04 2017 00:06:52 GMT+0800 (中国标准时间)/* 然后,1秒后 *///reject: Tue Jul 04 2017 00:06:53 GMT+0800 (中国标准时间)//633//reject: Tue Jul 04 2017 00:06:53 GMT+0800 (中国标准时间)
以上代码证明了第2,3,4点。而第一点和第五点通过以下代码证明:
let foo = new Promise(function (resolve, reject) { resolve(); console.log("in Promise");})console.log("after Promise");foo.then(function (arr) { console.log("in resolve");});console.log("at last");//in Promise//after Promise//at last//in resolve
证明除了resolve和reject中的代码是异步的之外,其他都是顺序执行(位于foo.then后的代码先执行,之后才执行了foo.then的回调函数)。
3、当两个Promise对象发生交互时
具体来说,Promise实例在执行回调函数时可以传一个参数,而这个参数可以是另外一个Promise实例的回调函数。如代码:
let foo = new Promise(function (res, rej) { setTimeout(function () { res("1") }, 1000)})let bar = new Promise(function (res, rej) { res(foo); //参数是foo实例})
在这种情况下,bar的回调函数并不会立即执行,而是会等待foo的状态改变后,再去执行bar的回调函数。
即当Promise实例bar的回调函数的参数是另外一个Promise实例foo时,bar在状态改变后不会立即执行,而是等待前一个Promise实例的状态发生改变后,他才会执行。
情况 foo bar 基本情况 一个Promise实例 bar的then的回调函数的参数是foo 延迟等待时间:foo小于bar 先执行 后执行 延迟等待时间:foo大于bar 先执行 等待foo执行完后即执行如代码:
let foo = new Promise(function (res, rej) { setTimeout(function () { res("1") }, 1500)})let bar = new Promise(function (res, rej) { setTimeout(function () { console.log(bar); }, 1000) setTimeout(function () { res(foo); }, 500)})let baz = new Promise(function (res, rej) { res("3");})foo.then(function (val) { console.log("foo: " + val);})bar.then(function (val) { console.log("bar: " + val);})baz.then(function (val) { console.log("baz: " + val);})//bar: 3//状态为"pending"//foo: 1//bar: 1
如上代码:
- bar因为没有延迟,也没有依赖,所以先执行了;
- bar虽然500ms后就可以执行,但因为依赖于bar,所以在等待foo执行,注意,此时其状态依然为pending,而不是resolved;
- foo在1500ms后执行完毕;
- bar发现foo执行完毕了,自己也可以执行,所以跟着执行了;
除此之外,还有几个特点:
- 作为参数的Promise实例,他会将自己的参数的值传递给另一个Promise实例,即bar的resolve的参数是foo,而foo的resolve的参数的值是”1”,因此bar的resolve的参数的值是”1”;
- 两个Promise实例要执行的必须都是resolve或者都是reject,不然不会互相影响;
阅读全文
0 0
- 从零开始学_JavaScript_系列(48)——Promise(1)基础知识
- 从零开始学_JavaScript_系列(51)——Promise(4)Promise.resolve和Promise.reject
- 从零开始学_JavaScript_系列(49)——Promise(2)then、值、catch
- 从零开始学_JavaScript_系列(50)——Promise(3)全部完成all和看谁最快race
- 从零开始学_JavaScript_系列(30)——NodeList
- 从零开始学_JavaScript_系列(32)——事件广播
- 从零开始学_JavaScript_系列(43)——Symbol简述
- 从零开始学_JavaScript_系列(47)——Reflect
- 从零开始学_JavaScript_系列(58)——Thunk函数
- 从零开始学_JavaScript_系列(59)——async函数
- 从零开始学_JavaScript_系列(27)——myblog的优化【1】样式表分离、localStorage
- 从零开始学_JavaScript_系列(53)——Generator函数(1)基本概念和示例
- 从零开始学_JavaScript_系列(60)——class(1)基本概念
- 从零开始学_JavaScript_系列(15)——js系列<3>(转为字符串,截取字符串)
- 从零开始学_JavaScript_系列(16)——js系列<5>(正则表达式)
- 从零开始学_JavaScript_系列(19)——js系列<6>闭包
- 从零开始学_JavaScript_系列(38)——对象的扩展(1)属性的简洁写法
- 从零开始学_JavaScript_系列(1)——dojo(8)(手把手教你封装一个widget)
- C++实现16进制字符串转换成int整形值
- request和response
- 阿里云ECS安全组常用操作汇总丨阿里云河南
- Git
- 分享Kali Linux 2017年第30周镜像文件
- 从零开始学_JavaScript_系列(48)——Promise(1)基础知识
- salesforce站点site调试debug方法
- Maven添加本地仓库
- js中concat函数使用
- java打开网页URI
- Android集成微信支付
- Javac编译原理
- 【Android】android镜像翻转
- 静态代码块static{}与非静态代码块{}