依据阮一峰ES6教程摘取的自己可能用到的特性
Promise
Promise 是一个对象,从它可以获取异步操作的消息,相当于一个容器,保存着某个未来才会结束的事件(一般是异步操作)的结果。
特点:
对象状态不受外界影响
一旦状态改变,就不会再变,任何时候都可以得到这个结果
无法取消Promise,一旦建立就立即执行,无法中途取消
内部抛出的错误,不会反应到外部
用法
异步图片加载
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;
});
}
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);
});
resolve和reject带参数时会传递到回调函数中
Promise.prototype.then()(状态改变时调用)
getJSON("/post/1.json").then(
post => getJSON(post.commentURL)
).then(
comments => console.log("resolved: ", comments),
err => console.log("rejected: ", err)
);
then()方法返回的是一个新的Promise实例,可以使用链式写法
Promise.prototype.catch()(.then(null,rejection)的别名)
p.then((val) => console.log('fulfilled:', val))
.catch((err) => console.log('rejected', err));
// 等同于
p.then((val) => console.log('fulfilled:', val))
.then(null, (err) => console.log("rejected:", err));
建议不再then()中定义reject状态函数,总是用catch方法。如果没有catch方法,promise会吃掉错误,不抛出信息
Promise.prototype.finally()(最后都会执行)
server.listen(port)
.then(function () {
// ...
})
.finally(server.stop);
不管最后的状态,执行完then或catch后,都会执行finally方法
Promise.all()(将多个Promise实例包装成一个新的实例)
// 生成一个Promise对象的数组
const promises = [2, 3, 5, 7, 11, 13].map(function (id) {
return getJSON('/post/' + id + ".json");
});
Promise.all(promises).then(function (posts) {
// ...
}).catch(function(reason){
// ...
});
只有当promises中的状态都fulfilled或一个rejected,才会调用后面的回调
Promise.race()(promise的回调会由率先改变的实例决定)
const p = Promise.race([
fetch('/resource-that-may-take-a-while'),
new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 5000)
})
]);
p
.then(console.log)
.catch(console.error);
如果5s内fetch无法返回结果,p状态就变为rejected,从而触发catch回调函数
Promise.resolve()(将现有对象转为Promise对象)
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
- 参数是一个Promise实例,直接Promise.resolve()即可
- 参数时一个thenable对象(具有then方法的对象)
let thenable = { then: function(resolve, reject) { resolve(42); } }; let p1 = Promise.resolve(thenable); p1.then(function(value) { console.log(value); // 42 });
- 参数是一个原始值或是一个不具有then方法的对象,则返回一个新的Promise对象,状态为resolved
const p = Promise.resolve('Hello'); p.then(function (s){ console.log(s) }); // Hello
- 不带任何参数时直接返回一个resolved状态的Promise对象
输出顺序,setTimeout实在下一轮‘事件循环’开始时执行,Promise.resolve()在本轮“事件循环”结束时执行setTimeout(function () { console.log('three'); }, 0); Promise.resolve().then(function () { console.log('two'); }); console.log('one'); // one // two // three
Promise.reject()(也返回一个新的Promise对象,状态为rejectd)
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))
p.then(null, function (s) {
console.log(s)
});
// 出错了
Promise.try()(不管同步函数或异步函数都可以处理)
const f = () => console.log('now');
Promise.resolve().then(f);
console.log('next');
// next
// now
Promise.try(f);
console.log('next')
//now
//next
上例中f如果是同步函数,用Promise包装后就变异步执行了,那么它会在本轮事件循环的末尾执行,用try可以解决,让异步按异步执行,让同步按同步执行
类似的方法还有
async函数,但不会抛出错误
const f = () => console.log('now');
(async () => f())();
console.log('next');
// now
// next
new Promise()
const f = () => console.log('now');
(
() => new Promise(
resolve => resolve(f())
)
)();
console.log('next');
// now
// next