ES6中的Promise深入解析
Posted 做人要厚道2013
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6中的Promise深入解析相关的知识,希望对你有一定的参考价值。
promise主要是为了解决回调带来的疯狂行为, Promise 风暴已经开始席卷javascript 世 界。
实际上,绝大多数 JavaScript/DOM 平台新增的异步 API 都是基于 Promise 构建的。
一. 异步编程的背景
JavaScript 的引擎建立在单线程事件轮询(single-threaded event loop)概念之上。
单线程意味着一段时间内只能执行一段代码,与 Java 和 C++ 这些允许多段代码同时执行的多线程语言形成了鲜明对比。
JavaScript 引擎在相同的时间内只能执行一段代码.
当代码由 JavaScript 引擎执行完毕后,引擎通过 event loop 找到并执行队列中的下一个任务。
event loop 是 JavaScript 引擎内部的线程用来监控代码的执行情况和管理任务队列。
需要牢记的是既然它是个队列,那么任务就会由开始到最后的顺序依次执行。
二. Promise出来之前的两种异步编程方式
- 事件模型
不够灵活.
- 回调模式
回调地狱
三. promise基础
一个 Promise 就是一个代表了异步操作最终完成或者失败的对象。
可以把Promise理解成对将来的一个”承诺”. 这个承诺不管将来如何一定会有一个结果:要么兑现承诺, 要么不兑现. 不管结果是什么, 都会对被承诺者一个交代.
我们通常有两种方式来获取到一个Promise
对象:
使用
Promise
构造函数来创建Promise
对象调用其他的一些
api
返回一个Promise
对象.(其实是这些api
内部创建并返回了Promise
对象)
我们先用第一种方式来深入的理解下promise
.
promise
的生命周期(The Promise Lifecycle)
每个 promise 的生命周期一开始都会处于短暂的挂起(pending)状态,表示异步操作仍未完成,即挂起的 promise 被认定是未定的(unsettled)。
一旦异步操作完成,promise 就被认为是已定(settled)的并处于以下的两种状态之一:
- fulfilled(resolved): promise 的异步操作已完成。
- rejected: promise 的异步操作未完成,原因可能是发生了错误或其它理由。
创建Promise
对象并添加异步任务
使用构造函数Promise
来创建Promise
对象.
需要接收一个执行函数(executor), 这个函数内包含了初始化Promise
的一些代码.
该执行函数接收 resolve 和 reject 两个参数(其实是两个函数)。
- resolve 函数会在执行函数成功运行后发出信号表示该 promise 已经可用,
- reject 函数代表改执行函数运行失败。
/*
对setTimeout 用promise作封装
创建出来一个未定的promise
注意:
1. 创建Promise对象的时候, 执行函数的内的代码会立即执行.
2. 当 resolve() 和 reject() 在执行函数内部被调用后,
为了处理这个 promise,一个任务会被放置到任务队列中。
该种行为被称为任务调度(job scheduling)
*/
var count = 1;
let promise = new Promise(function (resolve, reject)
if(count == 1)
resolve("成功了");
else
reject("失败了");
);
/*添加异步任务
* then需要两个函数:
* 函数1:异步操作成功之后的回调函数
* 函数2:异步操作失败之后的回调函数
* */
promise.then(function (value)
console.log(value);
, function (value)
console.log(value)
);
注意:
Promise
的意思是承诺,保证. 他带来了哪些保证呢?在JavaScript事件队列的当前运行完成之前,回调函数永远不会被调用。
- 通过
.then
形式添加的回调函数,甚至都在异步操作完成之后才被添加的函数,都会被调用 - 通过多次调用
.then
,可以添加多个回调函数,它们会按照插入顺序并且独立运行。
四. Promise
链式调用
一个常见的需求就是连续执行两个或者多个异步操作,这种情况下,每一个后来的操作都在前面的操作执行成功之后,带着上一步操作所返回的结果开始执行。
我们可以通过创造一个promise chain
来完成这种需求。
这也是Promise
的神奇之处.
是因为: 每次调用then
方法会返回一个全新的Promise
对象:
promise.then(function (value)
console.log(value);
, function (value)
console.log(value)
).then(function ()
console.log("哈哈哈")
)
在链中传递数据
promise.then(function (value)
console.log(value);
return value + "1"; // 给后面的异步任务传递数据
, function (value)
console.log(value)
).then(function (value)
console.log("哈哈哈", value)
)
五. 捕获错误
通过前面的学习我们已经知道, then
的第二个参数是用来处理错误.
其实我们可以省略这个参数不处理错误.
省略第二个参数:
promise.then(function (value)
console.log(value);
return value + "1";
)
也可以使用catch
来专门来处理错误:
promise.then(function (value)
console.log(value);
).catch(function (value)
console.log(value);
)
// 与下面完全等价:
promise.then(function (value)
console.log(value);
, function (value)
console.log(value);
console.log(a);
)
注意:
catch
也会返回一个新的promise
对象
六. 关于then
返回的promise
好好体会
then
方法总是返回一个新的Promise
,而它的行为与then
中的回调函数的返回值有关:
如果
then
中的回调函数返回一个值,那么then
返回的Promise
将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。如果
then
中的回调函数抛出一个错误,那么then返回的Promise将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。如果
then
中的回调函数返回的是一个promise A
, 那么then
返回的promise B
的状态始终会与promise A
保持一致. 并且回调函数的参数值也始终相同.promise A
的回调函数的参数也始终与promise B
的回调函数的参数保持一致.
使用promise封装ajax
以上是关于ES6中的Promise深入解析的主要内容,如果未能解决你的问题,请参考以下文章
执行 webpack.config 时出错 - 无法解析“es6-promise”