什么是Promise
Promise对象用于异步操作,它表示一个尚未完成且预计在未来完成的异步操作。
- 优点
(1) promise对象,进行链式回调,可以将 异步操作 以 同步操作的流程 表达出来,避免层层嵌套,避免"厄运回调金字塔"。
(2) 可以有多个then()连缀书写。
(3) 不仅给出了异步操作成功的代码解决方案,还给出了异步操作失败和完成的解决方案。
new Promise(function(resolve,reject){
//异步操作
}).then(function(){
//异步操作成功
}).catch(function(){
//异步操作失败
}).finally(function(){
//异步操作完成
})
- 缺点
(1) promise一旦新建,就会立即执行,无法取消
(2) 如果不设置回掉函数,promise内部抛出的错误就不会反应到外部
(3) 处于pending状态时,是不能知道目前进展到哪个阶段的 ( 刚开始?,即将结束?)
同步与异步
JavaScript的执行机制是「单线程」。
所谓的单线程,是指JS引擎中负责解释和执行JavaScript的代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完了之后才能执行下一个,它会「阻塞」其他任务。这个任务可称为主线程。
但实际上还有其他线程,如事件触发线程、ajax请求线程等。
这也就引发了同步和异步的问题。
同步
同步模式,即上述所说的单线程模式,一次只能执行一个任务,函数调用后需等到函数执行结束,返回执行的结果,才能进行下一个任务。如果这个任务执行的时间较长,就会导致「线程阻塞」。
var x = true;
while(x);
console.log("don't carry out"); //不会执行
这个例子就是同步模式,其中while是一个死循环,将会堵塞进程,所以第三句一直不会执行。
同步模式比较简单,也较容易编写。但问题也显而易见,如果请求的时间较长,而阻塞了后面代码的执行,体验是很不好的。因此对于一些耗时的操作,异步模式则是更好的选择。
异步
异步模式,即与同步模式相反,可以一起执行多个任务,函数调用后不会立即执行返回的结果。
setTimeout(function() {
console.log('taskA, asynchronous');
}, 0);
console.log('taskB, synchronize');
//while(true);
我们可以看到,计时器的时间为0,但是taskB还是比taskA先执行,这是因为定时器是异步的,异步问题会在当前脚本的所有同步任务执行完才会执行。
如果将上例注释去掉,这个异步(定时器)是不会执行的,成为了死循环,堵塞了同步任务进程。
Promise
//构建Promise
let promise = new Promise(function (resolve, reject) {
if (/* 异步操作成功 */) {
resolve(data);
} else {
/* 异步操作失败 */
reject(error);
}
});
promise.then(function(){
//书写调用了resolve()时执行的代码
},function(){
//书写调用了reject()时执行的代码
})
类似构建对象,我们使用new来构建一个Promise。Promise接受一个「函数」作为参数,该函数的两个参数分别是resolve和reject。这两个函数就是就是「回调函数」,由JavaScript引擎提供。
resolve函数的作用:在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用:在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise实例生成后,可以使用then方法指定resolve状态和reject状态的回调函数。
例 : 封 装 一 个 弹 框 ( c