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);
});

浙公网安备 33010602011771号