Promise
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
Promise,就是能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。
<div onClick={promiseClick}>开始异步请求</div>
const promiseClick =()=>{
console.log('点击方法被调用')
let p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('执行完成Promise');
resolve('要返回的数据可以任何数据例如接口返回数据');
}, 2000);
});
return p
}
promiseClick().then(function(data){
console.log(data);
//后面可以用传过来的数据做些其他操作
//......
});
控制台打印
精髓在于:Promise只是能够简化层层回调的写法,而实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。所以使用Promise的正确场景是这样的:
promiseClick()
.then(function(data){
console.log(data);
return runAsync2();
})
.then(function(data){
console.log(data);
return runAsync3();
})
.then(function(data){
console.log(data);
下面代码中,使用Promise包装了一个图片加载的异步操作。如果加载成功,就调用resolve方法,否则就调用reject方法。
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;
});
}
一般来说,调用resolve或reject以后,Promise 的使命就完成了,后继操作应该放到then方法里面,而不应该直接写在resolve或reject的后面(也就是说,resolve或reject应该是Promise中最后一行代码)。所以,最好在它们前面加上return语句,这样就不会有意外。
自己的理解:
1、Promise会像正常函数一样执行,执行到回调resolve时,也会像回调一样执行,执行完resolve后,根据回调resolve的执行结果触发状态改变,从pendding变成resolve或reject
2、then有两个参数,第一个参数,对应Promise的第一个参数resolve,即成功后的回调函数,如果then的第一个回调有参数,那么在Promise中调用resolve时,也要传参,如下代码;第二个参数是失败的回调函数,对应Promise中的reject,在Promise的逻辑中,如果有异常或者失败,可以执行reject回调,一般不会使用。
3、Promise是找个时机把then中要执行的函数插入到Promise的执行顺序中去。实际执行是按照代码顺序走的,从前往后执行多个promise,比一层一层的回调看着清晰。
new Promise((resolve, reject) => {
resolve(1);
console.log(2);
}).then(r => {
console.log(r);
});
es5的构造函数
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);
es6的class
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
Class 可以通过extends关键字实现继承。子类必须在constructor方法中调用super方法,否则新建实例时会报错。
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y); // 调用父类的constructor(x, y)
this.color = color;
}
toString() {
return this.color + ' ' + super.toString(); // 调用父类的toString()
}
}