es6 Promise 的基本用法
2018-01-27 22:25
441 查看
Promise 的基本用法
ES6 规定,Promise对象是一个构造函数,用来生成
Promise实例。
下面代码创造了一个
Promise实例。
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是
resolve和
reject。它们是两个函数,由
JavaScript 引擎提供,不用自己部署。
resolve函数的作用是,将
Promise对象的状态从“未完成”变为“成功”(即从
pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用是,将
Promise对象的状态从“未完成”变为“失败”(即从
pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise实例生成以后,可以用
then方法分别指定
resolved状态和
rejected状态的回调函数。
promise.then(function(value) {
// success
}, function(error) {
// failure
});
then方法可以接受两个回调函数作为参数。第一个回调函数是
Promise对象的状态变为
resolved时调用,第二个回调函数是
Promise对象的状态变为
rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受
Promise对象传出的值作为参数。
下面是一个
Promise对象的简单例子。
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
timeout(100).then((value) => {
console.log(value);
});
上面代码中,
timeout方法返回一个
Promise实例,表示一段时间以后才会发生的结果。过了指定的时间(
ms参数)以后,
Promise实例的状态变为
resolved,就会触发
then方法绑定的回调函数。
Promise 新建后就会立即执行。
let promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve();
});
promise.then(function() {
console.log('resolved.');
});
console.log('Hi!');
// Promise
// Hi!
// resolved
上面代码中,Promise 新建后立即执行,所以首先输出的是
Promise。然后,
then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以
resolved最后输出。
下面是异步加载图片的例子。
function loadImageAsync(url) {
return new Promise(function(resolve, reject) {
const image = new Image();
image.onload = function() {
resolve(image);
};
image.onerror = function() {
reject(new Error('Could not load image at ' + url));
};
image.src = url;
});
}
上面代码中,使用
Promise包装了一个图片加载的异步操作。如果加载成功,就调用
resolve方法,否则就调用
reject方法。
下面是一个用
Promise对象实现的 Ajax 操作的例子。
const getJSON = function(url) {
const promise = new Promise(function(resolve, reject){
const handler = function() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
const client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
});
return promise;
};
getJSON("/posts.json").then(function(json) {
console.log('Contents: ' + json);
}, function(error) {
console.error('出错了', error);
});
上面代码中,
getJSON是对 XMLHttpRequest 对象的封装,用于发出一个针对 JSON
数据的 HTTP 请求,并且返回一个
Promise对象。需要注意的是,在
getJSON内部,
resolve函数和
reject函数调用时,都带有参数。
如果调用
resolve函数和
reject函数时带有参数,那么它们的参数会被传递给回调函数。
reject函数的参数通常是
Error对象的实例,表示抛出的错误;
resolve函数的参数除了正常的值以外,还可能是另一个
Promise 实例,比如像下面这样。
const p1 = new Promise(function (resolve, reject) {
// ...
});
const p2 = new Promise(function (resolve, reject) {
// ...
resolve(p1);
})
上面代码中,
p1和
p2都是
Promise 的实例,但是
p2的
resolve方法将
p1作为参数,即一个异步操作的结果是返回另一个异步操作。
注意,这时
p1的状态就会传递给
p2,也就是说,
p1的状态决定了
p2的状态。如果
p1的状态是
pending,那么
p2的回调函数就会等待
p1的状态改变;如果
p1的状态已经是
resolved或者
rejected,那么
p2的回调函数将会立刻执行。
const p1 = new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('fail')), 3000)
})
const p2 = new Promise(function (resolve, reject) {
setTimeout(() => resolve(p1), 1000)
})
p2
.then(result => console.log(result))
.catch(error => console.log(error))
// Error: fail
上面代码中,
p1是一个 Promise,3 秒之后变为
rejected。
p2的状态在
1 秒之后改变,
resolve方法返回的是
p1。由于
p2返回的是另一个
Promise,导致
p2自己的状态无效了,由
p1的状态决定
p2的状态。所以,后面的
then语句都变成针对后者(
p1)。又过了
2 秒,
p1变为
rejected,导致触发
catch方法指定的回调函数。
注意,调用
resolve或
reject并不会终结
Promise 的参数函数的执行。
new Promise((resolve, reject) => {
resolve(1);
console.log(2);
}).then(r => {
console.log(r);
});
// 2
// 1
上面代码中,调用
resolve(1)以后,后面的
console.log(2)还是会执行,并且会首先打印出来。这是因为立即
resolved 的 Promise 是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。
一般来说,调用
resolve或
reject以后,Promise
的使命就完成了,后继操作应该放到
then方法里面,而不应该直接写在
resolve或
reject的后面。所以,最好在它们前面加上
return语句,这样就不会有意外。
new Promise((resolve, reject) => {
return resolve(1);
// 后面的语句不会执行
console.log(2);
})
相关文章推荐
- ES6基础之详解Promise基本用法
- ES6关于Promise的用法详解
- ES6 Promise对象概念与用法分析
- ES6的class方法基本用法
- Promise对象的含义和基本用法
- ES6 Promise对象概念及用法介绍
- Promise对象的含义和基本用法
- ES6 Promise 用法讲解
- 对Promise状态的理解和基本用法
- Promise对象的含义和基本用法
- 关于ES6中的promise用法以及在ajax中的应用
- es6 Promise简单用法例子
- promise的基本用法
- es6 async函数的基本用法
- ES6 Promise 用法讲解
- es6新特性之 class 基本用法解析
- Promise对象的含义和基本用法
- ES6的一些基本用法
- Promise对象的含义和基本用法
- [javascript高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race)