js的Promise
1、定时器都是异步操作
2、事件绑定都是异步操作
3、AJAX中一般我们都采取异步操作(也可以同步)
4、回调函数可以理解为异步(不是严谨的异步操作)
剩下的做同步处理
Promise详解
参考连接:
https://www.runoob.com/w3cnote/javascript-promise-object.html
Promise的三种状态
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态
一旦状态改变,就不会再变,任何时候都可以得到这个结果
Promise 对象的状态改变,只有两种可能
1.从 Pending 变为 Resolved
2.从 Pending 变为 Rejected
只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果
pending:
初始状态,不是成功或失败状态
fulfilled:
意味着操作成功完成。
rejected:
意味着操作失败。
Promise优缺点
优点
可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
Promise 对象提供统一的接口,使得控制异步操作更加容易
Promise 的最大问题是代码冗余,一眼看去都是一堆 then,语义变得很不清楚。
缺点
无法取消 Promise,一旦新建它就会立即执行,无法中途取消
如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部
Promise使用案例
入门案例
var myFirstPromise = new Promise(function(resolve, reject){ //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...) //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法. setTimeout(function(){ resolve("成功!"); //代码正常执行! }, 250); }); myFirstPromise.then(function(successMessage){ //successMessage的值是上面调用resolve(...)方法传入的值. //successMessage参数不一定非要是字符串类型,这里只是举个例子 document.write("Yay! " + successMessage); });
改变Promise状态案例
resolve 方法和 reject 方法调用时,都带有参数
它们的参数会被传递给回调函数
reject 方法的参数通常是 Error 对象的实例
而 resolve 方法的参数除了正常的值以外,还可能是另一个 Promise 实例
function ajax(URL) { return new Promise(function (resolve, reject) { var req = new XMLHttpRequest(); req.open('GET', URL, true); req.onload = function () { if (req.status === 200) { // 变为Resolved状态,用onFulfilled接收,意味着操作成功完成 resolve(req.responseText); } else { // 变为Rejected状态,用onRejected接收,意味着操作失败 reject(new Error(req.statusText)); } }; req.onerror = function () { // 变为Resolved状态,用onFulfilled接收,意味着操作成功完成 reject(new Error(req.statusText)); }; req.send(); }); } var URL = "/try/ajax/testpromise.php"; ajax(URL).then(function onFulfilled(value){ document.write('内容是:' + value); }).catch(function onRejected(error){ document.write('错误:' + error); }); // ------------------------------------------- // resolve 的参数为 另一个 Promise 案例 var p1 = new Promise(function(resolve, reject){ // ... some code }); var p2 = new Promise(function(resolve, reject){ // ... some code resolve(p1); })
Promise.prototype.then链式操作
依次指定了两个回调函数
第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数
getJSON("/post/1.json").then(function(post) { return getJSON(post.commentURL); }).then(function(comments) { // 对comments进行处理 });
Promise.prototype.catch
Promise.prototype.catch
方法是Promise.prototype.then(null, rejection)
的别名用于指定发生错误时的回调函数
Promise 对象的错误具有"冒泡"性质,会一直向后传递,直到被捕获为止
也就是说,错误总是会被下一个 catch 语句捕获
getJSON("/post/1.json").then(function(post) { return getJSON(post.commentURL); }).then(function(comments) { // some code }).catch(function(error) { // 处理前两个回调函数的错误 });
横向加载变为纵向
// 如果依次读取多个文件,就会出现多重嵌套。代码不是纵向发展,而是横向发展,很快就会乱成一团,无法管理 fs.readFile(fileA, function (err, data) { fs.readFile(fileB, function (err, data) { // ... }); }); // ----------------------------------- // Promise 的写法只是回调函数的改进,使用then方法以后,异步任务的两段执行看得更清楚了 var readFile = require('fs-readfile-promise'); readFile(fileA) .then(function(data){ console.log(data.toString()); }) .then(function(){ return readFile(fileB); }) .then(function(data){ console.log(data.toString()); }) .catch(function(err) { console.log(err); });