先列举下返回错误的值:
- false
- undefined
- null
- 0
- NaN
- 空字符串("")
try
try语句三种形式:
- try…catch
- try…finally
- try…catch…finally
无论经过try还是catch,最后都会进入finally
throw new Error(String) -->name, message
Promise(敲黑板)
Promise 是一个对象,代表一个异步操作的最终完成或者失败,是一个函数返回的对象,可以在它上面绑定回调函数,省去了把回调函数作为参数传入该函数。
Promise可解决:
- 回调地狱
做异步请求的时候,在请求成功的回调函数里继续写函数,或者继续发送异步,继续回调,回调函数里又回调,一层一层,嵌套越来越多,就会形成回调地狱。这会使我们的代码可读性变差,不好维护,性能也下降。
- 支持多个并发请求
- 配合async/await用同步代码写异步操作
Promise 对象有以下几种状态:
- pending:初始的状态,即正在执行,不处于 fulfilled 或 rejected 状态。
- fulfilled:成功的完成了操作。
- rejected:失败,没有完成操作。
- settled:Promise 处于 fulfilled 或 rejected 二者中的任意一个状态, 不会是 pending。
Promise 由pending一旦转为 fulfilled 或 rejected 二者中的任意一个状态, 此后便不会改变,也是这个词的由来鸭
创建
通过构造函数创建Promise实例
new Promise((resolve, reject) => {
resolve()/reject(new Error('error'))
})
.then(() => {})
.catch(err => { console.log(err) })
//或者
.then(() => {}, () => {})
构造函数Promise()能接收一个执行器(executor),即带有resolve和reject两个参数的函数,执行器会在构造函数返回新实例前被调用
-
在执行器中的异步操作完成时会调用resolve()函数,当前Promise的状态会根据它的参数发生变化。当参数为空或非Promise时,当前状态变成fulfilled;当参数是Promise时,当前Promise的状态和参数的相同。
-
在执行器中的异步操作错误时会调用reject()函数,当前Promise的状态会变成rejected。
then
在生成Promise实例之后,就能通过then()方法绑定状态变化后的回调函数(即处理方法),如下代码所示,此处是异步操作同步化的关键。
promise.then(function(value) {
// success
}, function(reason) {
// failure
});
thenable
包含then()方法的对象被称为thenable,所有的Promise都是thenable
Promise.resolve()能接收一个thenable,并返回一个新的Promise实例
var chain = new Promise(function(resolve, reject) {
reject("error");
});
chain.then(null, function(reason) {
console.log(reason); //"error"
return "end";
})
.then(function(value) {
console.log(value); //"end"
});
当返回值是一个非Promise的值时,其状态会变成fulfilled。
当回调函数抛出一个错误时,其状态会变成rejected。
当返回值是一个Promise时,其状态与返回值的相同。
静态方法
- resolve()
- reject()
- all()
- race()
resolve()
- 当参数为空或非thenable时,返回一个新的状态为fulfilled的Promise。
- 当参数为thenable时,返回一个新的Promise,而它的状态由自身的then()方法控制,具体细节已在之前的thenable一节做过说明。
- 当参数为Promise时,将不做修改,直接返回这个Promise。
let tha = {
then(resolve, reject) {
resolve("thenable");
}
};
//参数为空
Promise.resolve().then(function(value) {
console.log(value); //undefined
});
//参数为非thenable
Promise.resolve("string").then(function(value) {
console.log(value); //"string"
});
//参数为thenable
Promise.resolve(tha).then(function(value) {
console.log(value); //"thenable"
});
//参数为Promise
Promise.resolve(new Promise(function(resolve) {
resolve("Promise");
})).then(function(value) {
console.log(value); //"Promise"
});
reject()
此方法能接收一个参数,表示拒绝理由,它的返回值是一个新的已拒绝的Promise实例。与Promise.resolve()不同,Promise.reject()中所有类型的参数都会原封不动的传递给后续的已拒绝的回调函数,如下代码所示。
Promise.reject("rejected").catch(function (reason) {
console.log(reason); //"rejected"
});
var p = Promise.resolve();
Promise.reject(p).catch(function (reason) {
reason === p; //true
});
all()
- 当可迭代对象中的所有成员都是已完成的Promise时,新的Promise的状态为fulfilled。而各个成员的决议结果会组成一个数组,传递给后续的已完成的回调函数
var p1 = Promise.resolve(200), p2 = "fulfilled";
Promise.all([p1, p2]).then(function (value) {
console.log(value); //[200, "fulfilled"]
});
- 当可迭代对象中的成员有一个是已拒绝的Promise时,新的Promise的状态为rejected。并且只会处理到这个已拒绝的成员,接下来的成员都会被忽略,其决议结果会传递给后续的已拒绝的回调函数
var p1 = Promise.reject("error"),
p2 = "fulfilled";
Promise.all([p1, p2]).catch(function (reason) {
console.log(reason); //"error"
});
race()
只处理最先执行的一个
var p1 = new Promise(function(resolve) {
setTimeout(() => {
resolve("fulfilled");
}, 200);
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(() => {
reject("rejected");
}, 100);
});
Promise.race([p1, p2]).catch(function (reason) {
console.log(reason); //"rejected"
});
应用
与传统异步操作的组合
function preImg(src) {
return new Promise(function (resolve, reject) {
var img = new Image();
img.src = src;
img.onload = function(){
resolve(this);
};
img.onerror = function(){
reject(this);
};
});
};
preImg("img/page.png").then(function(value) {
console.log(value);
});