Promise 是什么
Promise 是 ES6 为 JavaScript 异步编程定义的全新 api 。为异步编程而生,实际上就是另类的回调函数。
为什么要使用 Promise
- 代码更整洁,可读性强,易于维护(避免了回调地狱)。
- 链式操作,容易编写,易于开发。
API速查
- promiseObj.then( resolve, reject )
- promiseObj.catch( reject ) =====>(等同于 promiseObj.then( null, reject ))
- Promise.resolve() =====>创建一个已完成态的 promise 对象
- Promise.reject() =====>创建一个已拒绝态的 promise 对象
使用方法
promise() 之后总是会返回一个新的 promise 对象,因此而支持链式操作。
1.基本用法
const _p = new Promise((resolve, reject) => {
console.log(1);
resolve(2);
});
_p.then(
res => {
console.log(res);
},
err => {
console.log(err);
}
);
*************
1
2
resolve
为当异步处理“成功”时调用的方法;reject
为异步处理“失败”时调用的方法。
2.链式操作
const _p = new Promise((resolve, reject) => {
console.log(1);
resolve(2);
});
_p.then(
res => {
console.log(res);
return 3; //把想要继续操作的数据 return 出来
},
err => {
console.log(err);
}
).then(res => {
console.log(res);
});
*******************
1
2
3
行为探究
1.时效性
const _p = new Promise((resolve, reject) => {
console.log(1); // 这一条语句模拟了声明内容
resolve(2);
});
_p.then(res => {
console.log(res);
return 3;
}).then(res => {
console.log(res);
});
*************
1
2
3
const _p = new Promise((resolve, reject) => {
//这里属于声明内容
setTimeout(() => {
console.log(1);
resolve(2);
}, 1000);
});
_p.then(res => {
console.log(res);
return 3;
}).then(res => {
console.log(res);
});
******************
1 //1秒后打印
2 //1秒后打印
3 //1秒后打印
const getp = () => {
//这里的 promise 对象是函数返回结果,所以直到函数 getp 被调用之前,
//该promise 的声明内容都不在主线程当中,所以不会被立即执行。
return new Promise((resolve, reject) => {
console.log(1);
resolve(2);
});
};
setTimeout(() => {
const _p = getp();
_p.then(res => {
console.log(res);
return 3;
}).then(res => {
console.log(res);
});
}, 2000);
**************
1 //2秒后打印
2 //2秒后打印
3 //2秒后打印
let _p = new Promise((resolve, reject) => {
console.log(1);
resolve(2);
});
//完成处理程序
_p = _p.then(res => {
console.log(res);
return 3;
});
//完成处理程序
_p.then(res => {
console.log(res);
return 4;
});
console.log(11);
*****************
1
11
2 //完成处理程序被添加至任务队列末尾
3 //完成处理程序被添加至任务队列末尾
【结论】
1. promise 的声明环境如果在主线程当中,那么其声明内容会被立即调用一次;而在 resolve
和 reject
中传入的参数知道有下一次 .then() 动作时才会被使用。
2. promise 的完成处理程序(resolve
)和拒绝处理程序(reject
)总是在执行器完成后被添加到任务队列的末尾。
2.报错机制
const _p = new Promise((resolve, reject) => {
throw new Error(233);
});
_p.then(
res => {
console.log(res);
return 3;
}
//此处不注册拒绝处理程序
);
***************
弹出错误
const _p = new Promise((resolve, reject) => {
throw new Error(233);
});
_p.then(
res => {
console.log(res);
return 3;
},
//注册拒绝处理程序
err => {
console.log(err);
}
);
***************
不弹出错误,打印错误信息
const _p = new Promise((resolve, reject) => {
throw new Error(233);
});
_p.then(
res => {
console.log(res);
return 3;
},
//注册拒绝处理程序(但没有任何动作)
err => {
//console.log(err);
}
);
***************
完全不报错
const _p = new Promise((resolve, reject) => {
console.log(2);
resolve(2);
console.log(3);
throw new Error(233);
console.log(4);
});
_p.then(
res => {
console.log(res);
return 3;
},
//无论是否注册拒绝处理程序
err => {
console.log(err);
}
);
*********
2
3
2
完全不报错
const _p = new Promise((resolve, reject) => {
console.log(2);
throw new Error(233);
console.log(3);
resolve(2);
console.log(4);
});
_p.then(
res => {
console.log(res);
return 3;
},
err => {
console.log(err);
}
);
**********
2
打印错误信息
【结论】
1. 在 promise 进程中如果先遇到了 resolve
则后续即便遇上 error 也不会调用 reject
;反之如果先遇到 error 则直接调用 reject
,且永远不调用完成处理程序。
上面的例子我们发现
resolve
之后的语句依然会被执行,直到遇见 error 或结束;反之 Error 之后的语句则无论如何都不会被执行了。
2. 永远不要声明一个什么都不做的拒绝处理函数,因为你可能会在出现bug时得不到任何有效信息。
------------- 作者水平有限,如有错误,欢迎探讨指正 -------------
网友评论