一、什么是Promise
Promise 是抽象的异步处理对象,以及对其进行各种操作的组件。
Promise最初被提出是在 E语言中, 它是基于并列/并行处理设计的一种编程语言。Javascript 在 ES6 之后也开始支持 Promise 特性了,用来解决异步操 的问题。这里顺便解释一下什么是 ES6, ECMAScript 是 Javascript 语言的国际标准,Javascript 是 ECMAScript 的有一个实现, 而ES6(全称 ECMAScript 6)是这个标准的一个版本。
谈到异步操作,你可能会说,Javascript 不是可以用回调 函数处理异步操作吗? 原因就是 Promise 是一种更强大的异步处理方式,而且她有统一的 API 和规范。
二、promise的用法
- Promise是一个构造函数,所以可以 new 出一个Promise的实例
- 在Promise上有两个函数 resolve(成功之后的回调函数)和 reject(失败后的回调函数)
- 在Promise构造函数的prototype属性上,有一个 .then() 方法。所以只要是Promise构造函数创建的实例,都可以访问到 .then()方法
- Promise表示一个一步操作,每当我们new一个Promise的实例,这个实例就代表具体的异步操作。
- Promise创建的实例,是一个异步操作,这个异步操作结果,只有两种结果
状态1:异步执行成功,需要在内部调用成功的回调函数resolve把结果返回给调用者(Fulfilled状态)
状态2:异步执行失败,需要在内部调用失败的回调函数reject把结果返回调用者(Rejected状态)
(注:其实Promise创建示例时还有一个Pending状态,但不存在于操作结果内,表示待解决,既不是resolve也不是reject的状态。也就是promise对象刚被创建后的初始化状态.)
- 由于Promise的实例是一个异步操作,所以内部拿到操作结果后,无法使用return把操作结果返回给调用者,这个时候只能使用回调函数的形式,把成功或失败的结果,返回给调用者
我们可以在new出来的Promise实例上,调用 .then()方法,预先为这个Promise异步操作,指定成功(resolve)和失败(reject)回调函数
在 ES6 中,可以使用三种办法创建 Promise 实例(对象)
(1). 构造方法
let promies = new Promise((resolve, reject) => { resolve(); //异步处理 });
Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 和 reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
(2). 通过 Promise 实例的方法,Promise#then 方法返回的也是一个 Promise 对象
promise.then(onFulfilled, onRejected);
(3). 通过 Promise 的静态方法,Promise.resolve(),Promise.reject()
var p = Promise.resolve(); p.then(function(value) { console.log(value); });
示例:创建一个完整的方法(下面的函数aa,bb均可创建)
function aa() { var p = new Promise((resolve, reject) => { alert('处理过程'); resolve("结果") }) return p; } function bb() { var p = new Promise(function (resolve, reject) { alert('处理过程,得到结果'); resolve("结果") }) return p; }
我对他的简单理解就是:aa函数委托promise做事情,alert()的部分代替了事件处理的过程,resolve()中的内容代表事件处理的结果,然后return p相当于promise处理完aa交代的事件后给它返回一个交代。上述示例除了resolve外,还有可以有reject(),reject()代表事件处理没有办成的一个结果。
可以直接使用reject()方法或resolve()方法,表示Promise
被拒绝的原因或继续执行。
Promise.reject(reason); //或
var promise1 = Promise.resolve(123);
promise1.then(function(value) {
console.log(value);
// expected output: 123
});
下面给一个完整的例子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <h2>需求:promise执行解决晚餐过程</h2> <br> 1.煲汤 <br> 2.洗菜 <br> 3.做饭 <br> 4.吃饭 <br>
5.洗碗 <br> </body> <script> let condition =true; function step1(resolve,reject){ console.log("放料,加水,插电"); if(condition==true){ resolve("煲好汤了") }else{ reject("没电了") } } function step2(resolve,reject){ console.log("洗菜"); if(condition==true){ resolve("洗好了"); }else{ reject("没水了"); } } function step3(resolve,reject){ console.log("开始做饭"); if(condition==true){ resolve("做好了"); }else{ reject("没火了"); } } function step4(resolve,reject){ console.log("准备吃饭"); if(condition==true){ resolve("真好吃"); }else{ reject("真难吃"); } } function step5(resolve,reject){ console.log("准备洗碗"); if(condition==false){ resolve("不想洗"); }else{ reject("洗"); } } new Promise(step1).then((val1)=>{ console.log(val1); return new Promise(step2) }).then((val2)=>{ console.log(val2); return new Promise(step3) }).then((val3)=>{ console.log(val3) return new Promise(step4) }).then((val4)=>{ console.log(val4) return new Promise(step5) }).then((val5)=>{ console.log(val5) }) </script> </html>
三、Promise.all()方法
Promise.all(iterable)
方法返回一个 Promise实例,此实例在 iterable
参数内所有的 promise
都“完成(resolved)”或参数中不包含 promise
时回调完成(resolve);如果参数中 promise
有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise
的结果。即多个promise都执行,全部执行完之后再执行下一步。
var promise1 = Promise.resolve(3); var promise2 = 42; var promise3 = new Promise(function(resolve, reject) { setTimeout(resolve, 100, 'foo'); }); Promise.all([promise1, promise2, promise3]).then(function(values) { console.log(values); }); // expected output: Array [3, 42, "foo"]
四、Promise.prototype.then()方法
Promise.prototype.then()即当promise执行完后,再执行某一函数
var promise1 = new Promise(function(resolve, reject) { resolve('Success!'); }); promise1.then(function(value) { console.log(value); // expected output: "Success!" });
五、Promise.prototype.catch()方法
catch() 方法返回一个Promise,并且处理拒绝的情况。它的行为与调用Promise.prototype.then(undefined, onRejected)
相同,即当执行失败时返回一个函数。
p.catch(onRejected); p.catch(function(reason) { // 拒绝 });
六、Promise.prototype.finally()方法
finally()
方法返回一个Promise
,在promise执行结束时,无论结果是fulfilled或者是rejected,在执行then()
和catch()
后,都会执行finally
指定的回调函数。这为指定执行完promise后,无论结果是fulfilled还是rejected都需要执行的代码提供了一种方式,避免同样的语句需要在then()
和catch()
中各写一次的情况。
p.finally(onFinally); p.finally(function() { // 返回状态为(resolved 或 rejected) });参数
七、Promise.prototype.race()方法
Promise.race(iterable)
方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
var promise1 = new Promise(function(resolve, reject) { setTimeout(resolve, 500, 'one'); }); var promise2 = new Promise(function(resolve, reject) { setTimeout(resolve, 100, 'two'); }); Promise.race([promise1, promise2]).then(function(value) { console.log(value); // Both resolve, but promise2 is faster }); // expected output: "two"
八、dojo中的Promise方法
1、dojo/promise/Promise
dojo / promise / Promise定义了Dojo Promises API,是一个抽象类。 例如,dojo / Deferred实现了类。该类旨在封装异步线程之间的通信。
define(["dojo/promise/Promise", "dojo/_base/declare"], function(Promise, declare){ return declare([Promise], { then: function(){ // Implementation of .then() }, cancel: function(){ // Implementation of .cancel() }, isResolved: function(){ // Implementation of .isResolved() }, isRejected: function(){ // Implementation of .isRejected() }, isFulfilled: function(){ // Implementation of .isFulfilled() }, isCanceled: function(){ // Implementation of .isCanceled() } }); });
2、dojo/promise/all
dojo / promise / all是一个函数,它接受多个promise并返回一个新的promise,当所有promises都已完成时,它将被履行。
require(["dojo/promise/all"], function(all){ all([promise1, promise2]).then(function(results){ // results will be an Array }); // -- or -- all({ promise1: promise1, promise2: promise2 }).then(function(results){ // results will be an Object using the keys "promise1" and "promise2" }); });
3、dojo/promise/first
dojo / promise / first是一个函数,它接受多个promise并返回一个新的promise,当第一个promise完成时,它会被满足。
require(["dojo/promise/first"], function(first){ first([promise1, promise2]).then(function(result){ // result will be either promise1 or promise2 results, whichever is fulfilled first }); // -- or -- first({ promise1: promise1, promise2: promise2 }).then(function(result){ // result will be either promise1 or promise2 results, whichever is fulfilled first }); });