1丶什么是Promise?
Promise是异步编程的一种解决方案。最初被提出是在 E语言中, 它是基于并列/并行处理设计的一种编程语言。 现在JavaScript也拥有了这种特性,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
2丶Promise状态
Fufilled:已成功
Rejected:已失败
Pending:初始状态、进行中
3丶Promise.prototype.then( )
代码段例子
function taskA() {
console.log("Task A");
}
function taskB() {
console.log("Task B");
}
function onRejected(error) {
console.log("Catch Error: TaskA or TaskB", error);
}
function finalTask() {
console.log("Final Task");
}
let promise = Promise.resolve();
promise
.then(taskA)
.then(taskB)
.catch(onRejected)
.then(finalTask);
按顺序正常执行:
会按照TaskA → TaskB→ FinalTask 这个流程来进行处理。
Task A产生异常:
会按照TaskA → onRejected → FinalTask 这个流程来进行处理
注意:每次调用then都会返回一个新创建的promise对象
4丶Promise 参数传递
看代码
function doubleUp(value) {
return value * 2;
}
function increment(value) {
return value + 1;
}
function output(value) {
}
console.log(value);
let promise = Promise.resolve(1);
promise.then(increment)
.then(doubleUp)
.then(output)
.catch(function (error) {
// promise 出错时会调用
});
console.error(error);
//等于ES6如下写法
let promise = Promise.resolve(1);
promise.then(value => value + 1)
.then(value => value * 2)
.then(value => console.log(value))
.catch(error => console.error(error));
这段代码的入又函数是 Promise.resolve(1); 整体的执行流程如下。
1、Promise.resolve(1); 传递 1 给 increment 函数
2、函数 increment 对接收的参数进行 +1 操作并返回(通过return)
3、这时参数变为2,并再次传给 doubleUp 函数
4、最后在函数 output 中打印结果
5丶Promise.prototype.catch()
Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。
let promise = Promise.reject(new Error("message"));
//1、catch
promise.catch(function (error) {
console.error(error);
});
//2、.then(undefined,onRejected)
promise.then(undefined,error => console.error(error));
如果Promise状态已经变成resolved,再抛出错误是无效的.因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。
const promise = new Promise((resolve,reject) => {
resolve('OK');
throw new Error('test')
});
promise.then(value => console.log(value))//error不再会被捕获
6丶Promise.finally()
finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。
promise
.then(result => {...})
.catch(error => {...})
.finally(() => {...});
finally本质上是then方法的特例
promise
.finally(() => {
// ...任务
});
// 等同于
promise
.then(
result => {
// ...任务
return result;
},
error => {
// ...任务
throw error;
}
);
finally实现
Promise.prototype.finally = function (callback) {
let P = this.constructor;
return this.then(
value => P.resolve(callback()).then(() => value),
reason => P.resolve(callback()).then(() => {
throw reason
})
);
};
7丶Promise.all() 和 Promise.race()
Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。只有这多个Promise实例的状态都变成fulfill,或者其中有一个变成rejected,才会调
用Promise.all后面的回调函数
Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。但是只要有一个Promise实例状态改变,Promise.race的状态就会改变。
Promise.all示例:
// `delay`毫秒后执行resolve
// `delay`毫秒后执行resolve
function timerPromisefy(delay) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(delay);
}, delay);
});
}
let startDate = Date.now();
// 所有promise变为resolve后程序退出
Promise.all([
timerPromisefy(1),
timerPromisefy(32),
timerPromisefy(64),
timerPromisefy(128)
]).then(function (values) {
console.log(Date.now() - startDate + 'ms');
// 約128ms
console.log(values); // [1,32,64,128]
});
Promise.race示例:
// `delay`毫秒后执行resolve
function timerPromisefy(delay) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(delay);
}, delay);
});
}
let startDate = Date.now();
Promise.race([
timerPromisefy(1),
timerPromisefy(32),
timerPromisefy(64),
timerPromisefy(128)
]).then(function (values) {
console.log(Date.now() - startDate + 'ms');
console.log(values); // 1
});