Promise(常用方法)

参考原文 http://es6.ruanyifeng.com/#docs/promise

Promise 的含义

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。

从语法上讲,Promise是一个对象,从它可以获取异步操作的信息

主要好处:

  • 可以避免多层异步通用嵌套问题(回调地狱)。
  • Promise对象提供了简洁的API,使得控制异步操作更加容易。


基本用法

ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。

下面代码创造了一个Promise实例。

1
2
3
4
5
6
7
8
9
const promise = new Promise(function(resolve, reject) {
// ... some code

if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);js
}
});

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;

reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

1
2
3
4
5
promise.then(function(value) {
// success
}, function(error) {
// failure
});

then方法可以接受两个回调函数作为参数。

第一个回调函数是Promise对象的状态变为resolved时调用,

第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。


在原生JS中发送Ajax的用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 function getJSON(url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState != 4) return;
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(xhr.responseText);
} else {
reject('服务器错误')
}
};
xhr.open('get', url);
xhr.send();
});
}
getJSON("/posts.json").then(
json => console.log('Contents: ' + json),
error => console.error('出错了', error)
);

在jQuery中发送Ajax的用法

1
2
3
4
5
6
7
8
9
10
function getJSON(url){
return $.ajax({
url: "url",
dataType: "json",
})
}
getJSON().then(
json => console.log('Contents: ' +json),
error => console.error('出错了', error)
);


实例方法

Promise.prototype.then()

得到异步任务的结果

1
2
3
4
5
promise.then(function(value) {
// resolved状态
}, function(error) {
// rejected状态
});

它的作用是为 Promise 实例添加状态改变时的回调函数。

then方法的参数 :(都是函数)

  • 第一个参数是resolved状态的回调函数
  • 第二个参数(可选)是rejected状态的回调函数。

then方法的返回值

  • 返回promise实例对象

    返回的实例对象会调用下一个then

    1
    2
    3
    4
    5
    6
    7
    getJSON("/post/1.json").then(function(post) {
    return getJSON(post.commentURL);
    }).then(function (comments) {
    console.log("resolved: ", comments);
    }, function (err){
    console.log("rejected: ", err);
    });
  • 返回普通值

    返回的普通值会直接传递给下一个then,通过then参数中函数的参数接收。

    实际上返回的还是Promise实例(默认的),因此可以通过.then方法调用。

1
2
3
4
5
getJSON("/posts.json").then(function(json) {
return 'hello'; // 返回字符串
}).then(function(post) {
console.log(post) // hello
});

Promise.prototype.catch()

获取错误的信息

Promise.prototype.catch方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

1
2
3
4
5
6
getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 处理 getJSON 和 前一个回调函数运行时发生的错误
console.log('发生错误!', error);
});

Promise.prototype.finally()

成功与否都会执行

finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

1
2
3
4
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

上面代码中,不管promise最后的状态,在执行完thencatch指定的回调函数以后,都会执行finally方法指定的回调函数。



对象方法

Promise.all()

并发处理多个异步任务,所有任务都执行完成才能得到结果

1
2
3
4
5
6
var p1 = getJSON('url1');
var p2 = getJSON('url2');
var p3 = getJSON('url3');
Promise.all([p1, p2, p3]).then(function (json) {
console.log(json) // 按照顺序返回得到的结果
})

Promise的状态由p1p2p3决定,分成两种情况。

(1)只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。


Promise.race()

并发处理多个异步任务,只要有一个任务完成就能得到结果

1
2
3
Promise.race([p1, p2, p3]).then(function (json) {
console.log(json) // 返回第一个得到的结果
})

Promise的状态由p1p2p3决定

如果指定时间内没有获得结果,就将 Promise 的状态变为reject,否则变为resolve


 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×