promise 基础学习

Promise 是ES6的特性之一,采用的是 Promise/A++ 规范,它抽象了异步处理的模式,是一个在JavaScript中实现异步执行的对象。
按照字面释意 Promise 具有“承诺”的含义,它承诺当异步处理完成后,回馈一个结果给你!或者你可以将其认为是一个状态机,一旦状态发生了改变,便会触发对应的行为。

Promise 最早出现于E语言中(一种给予并列/并行处理设计的编程语言),JavaScript 引入这一特性,旨在为了规范异步的操作和避免陷入回调地狱。

如何使用?

Promise的使用主要有两种方式,一种是对象实例化操作,它具有固定的使用格式:

new Promise(exector);

具体示例:

var promise = new Promise(function(resolve,reject){ if(success){ resolve(); }else{ reject(); } })

exector 是一个作为参数的匿名函数,它接收两个参数,一个是 resolve ,另一个则是 reject,这两个参数都是方法,通过执行两个方法我们可以修改 Promise 实例对象的状态,使其再触发对应的行为。

另一种则是静态调用,这些方法本身就是 Promise 对象的静态实现:

Promise.resolve().then(resolve); Promise.reject().then(undefined,rejected); Promise.reject().catch(rejected);

静态调用常用于快速执行一个异步操作,例如在我们的程序功能中有一个耗时很长的循环,这个循环的目的只是为了计算一个结果并显示,但是若直接放在程序的上下文的地方,会导致阻塞,常用的方式是将其加入到一个定时器中进行异步操作:

setTimeout(function(){ for(;;){;} },16);

但是学习了静态调用 Promise,我们完全可以将这个操作放入到要给 Promise的异步回调中。

Promise.resolve().then(function(){ for (var i = 0; i < 100000; i++) { if(i === 100000/2){ console.log('loop end2'); } } });

对比这两种方式,不难发现通过对象实例的方式,我们可以为实例对象赋予更多的功能,可以根据自身的需要手动的改变 Promise 的状态,而使用静态调用的方式,则可以快速的进行异步操作。
需要注意的是,不论是静态的方式还是实例化对象,根据Promise的状态被调用的方法都是以异步方式执行的。但是 Promise 对象实例化的过程却依然是同步的。

Promise的状态

Promise 有三种状态:pendding、rejected、fulfilled;

pendding : 表示初始化状态

rejected : 表示失败状态

fulfilled: 表示成功完成状态

而状态的变化,则需要通过执行对应的方法来完成,

pendding -> fulfilled 通过 resolve() 方法来完成。

pendding -> rejected : 通过 reject() 方法来完成。

Promise 默认的状态是 pendding 状态,这种状态出现在实例对象刚刚初始化的情况,结束于 resolve() 或者是 reject() 方法调用之后。一旦状态发生改变,便无法再修改,也因此说明,状态改变后执行的回调操作 then 也只会执行一次。除此之外,在 Promise 中主动使用 throw new Error() 也可以使 promise的状态改变为 rejected。

Promise的简单示例

Promise 的实例对象一旦创建好后,会大致具有以下的操作:

初始化状态为pendding 。

附加 then、catch 等异步处理方法

执行 exector 方法(同步的方式),根据具体的行为来决定是否变更 promise实例对象的状态。

实际上通过静态调用的方式来执行 Promsie,除了不具有 exector 其它的都是相同的。
需要着重说明的是 then 与 catch 这两个方法,它们都是 Promise对象的状态回调函数,一旦 promise的状态发生改变,便会对应的进行触发。

var promise = new Promise(function(resolve, reject) { var num = Math.random() * 5; setTimeout(function() { if (num >= 2.5) { reject('数值过大'); } else { resolve(num); } }, 1000) }); promise.then(function(v) { console.log('success:' + v); }, function(v) { console.log(v) });

then 方法有两个参数:promise.then(onResolved,onRejected),其中 onResolved 表示成功(状态变更为 fulfilled)的回调函数,而 onRejected 则表示失败(状态变更为 rejected)情况下的回调函数,一般来说第二个参数可以忽略不写,只保留成功的回调方法 then(onResolved),但是如果你只想处理失败的回调函数,那么 onResolved 并不能被省去,promise.then(undefined,onRejected)。

或者将 rejected 的处理单独提取出来是更好的办法:

promise.then(function(v) { console.log('success:' + v); }).catch(function(v) { console.log(v) });

Promsie 支持这种类似JQ的链式调用,并且可以同时连续调用多个 then 方法,而这里的 catch 方法与我们的 try..catch 功能相同,都是用于捕获错误。而且还可以将错误单独的提取出来,这便为我们带来一个非常大的优势那就是哪怕我then方法中的 onResolved 方法执行错误,也不会阻塞其它代码的执行。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpsgdy.html