原文網址:JS--Promise--使用/教程/實體_IT利刃出鞘的博客-CSDN博客
簡介
說明
本文用示例介紹JavaScript的Promise,它是ES6新增的特性,
Promise的用途
- 用來異步編程
- 解決回呼地獄(也稱為:厄運金字塔)
- 在異步呼叫中再次進行異步回呼,如果嵌套的層級太多,會導致難以維護,
Promise 的三種狀態
- pending:等待(初始狀態)
- 在 resolve 被呼叫時變為 "fulfilled",
- 在reject 被呼叫時變為 "rejected" ,
- fulfilled:已完成
- rejected:已失敗,(已拒絕)
狀態變為resolved 或 rejected 之后,就不會再次改變,這兩個狀態被稱為 “settled”(已定型),
用法簡介
簡述
Promise 都有這些內容:建構式、物件的實體方法、靜態方法
- 1個建構式:new Promise
- 3個物件的實體方法:.then 和 .catch 和 finally(不常用)
- 5個靜態方法:Promise.all、Promise.allSettled、Promise.race、Promise.resolve、Promise.reject
then與catch
.catch(f) 呼叫是 .then(null, f) 的完全的模擬,它只是一個簡寫形式,
then與catch只用一個即可,一般用then,因為它可以處理成功(fulfilled)與失敗(rejected),而catch只能處理失敗(rejected),
下邊程式中,會進行reject,后續then會執行,.catch不會執行,finally會執行,
let promise = new Promise(function (resolve, reject) {
setTimeout(() => {
reject("定時任務結果(reject)");
}, 1000);
});
promise
.then(
result => console.log("成功(then):" + result),
error => console.log("錯誤(then):" + error)
)
.catch(
error => console.log("錯誤(catch):" + error)
)
.finally(
() => console.log("運行結束(finally)")
);
結果
錯誤(then):定時任務結果(reject)
運行結束(finally)
resolve與reject
resolve方法:
通過回呼里的 resolve(data) 將這個狀態標記為 fulfilled,然后進行下一步 then((data)=>{//do something}),resolve 里的data就是你要傳入 then 的data,
reject方法:
通過回呼里的 reject(data) 將這個狀態標記為 rejected,然后進行下一步 then((data1, data2)=>{//do something}),resolve 里的data就是你要傳入 then 的data2,
executor 只能呼叫一個 resolve 或一個 reject ,所有其他的 resolve 和 reject 的呼叫都會被忽略:
let promise = new Promise(function(resolve, reject) {
resolve("done");
reject(new Error("…")); // 被忽略
setTimeout(() => resolve("…")); // 被忽略
});
示例:異步編程
示例1:resolve(成功)
let promise = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve("定時任務結果(resolve)");
}, 1000);
});
promise
.then(
result => console.log("成功(then):" + result),
error => console.log("錯誤(then):" + error)
)
.finally(
() => console.log("運行結束(finally)")
);
結果
成功(then):定時任務結果(resolve)
運行結束(finally)
示例2:reject(失敗)
let promise = new Promise(function (resolve, reject) {
setTimeout(() => {
reject("定時任務結果(reject)");
}, 1000);
});
promise
.then(
result => console.log("成功(then):" + result),
error => console.log("錯誤(then):" + error)
)
.finally(
() => console.log("運行結束(finally)")
);
結果
錯誤(then):定時任務結果(reject)
運行結束(finally)
示例:解決回呼地獄
什么是回呼地域?
在異步呼叫中再次進行異步回呼,如果嵌套的層級太多,會導致難以維護,這就是回呼地獄,
例如:使用ajax請求url,成功后再請求url1,成功后再請求url2,代碼會是下邊這個樣子:
ajax(url, () => {
// 處理邏輯
ajax(url1, () => {
// 處理邏輯
ajax(url2, () => {
// 處理邏輯
})
})
})
為了方便演示,本處采用定時任務的方式進行演示,
需求:每1秒鐘輸出一次,分別輸出:first、second、third、end,
復現回呼地獄
let fn = function (order, callback) {
setTimeout(function () {
console.log(order);
callback();
}, 1000);
}
fn("first", function () {
fn("second", function () {
fn("third", function () {
console.log("end");
});
});
});
結果
first
second
third
end
Promise解決回呼地獄
let fn = function (order) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(order);
//異步操作執行完后執行 resolve() 函式
resolve();
}, 1000);
});
}
fn("first")
.then(function () {
//仍然回傳一個 Promise 物件
return fn("second");
})
.then(function () {
return fn("third");
})
.then(function () {
console.log('end');
})
結果
first
second
third
end
async + await 解決回呼地獄
async + await是對promise的進一步封裝,
let fnTimeOut = function (order) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(order);
//異步操作執行完后執行 resolve() 函式
resolve();
}, 1000);
}
);
};
async function fn() {
let first = await fnTimeOut("first");
let second = await fnTimeOut("second");
let third = await fnTimeOut("third");
console.log("end");
}
fn();
結果
first
second
third
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/401655.html
標籤:其他
