一、什么是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 }); });
浙公网安备 33010602011771号