目錄
- 概述
- 詳論
- 回呼地獄
- Promise實作
- 參考
??概述
在上一篇文章《JavaScript異步編程2——結合XMLHttpRequest使用Promise》中,簡要介紹了Ajax與Promise的結合使用,這樣,我們就有了兩個異步操作的例子:讀取一個json檔案;通過一個地址加載影像,考慮一下,如果存在兩個異步操作,它們需要在執行一個操作之后再執行另外一個操作(例如在這里,我們把影像地址存盤在json檔案中,通過訪問json中的地址來加載影像),該如何做呢?
??詳論
1??回呼地獄
為了實作上面說到的功能,假如我們不使用Promise,直接使用回呼函式當然也可以實作:
$(function () {
var url = "./1.json";
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function () {
if (req.status == 200) {
var imgJson = JSON.parse(req.response);
var img = new Image();
img.onload = function () {
$(img).appendTo($('#container'));
};
img.onerror = function () {
throw new Error("Load Image Error!");
}
img.src = https://www.cnblogs.com/charlee44/archive/2021/05/03/imgJson[0];
} else {
throw new Error(req.statusText);
}
};
req.onerror = function () {
throw new Error("Network Error");
};
req.send();
});
可以看到這里我們使用了兩層的嵌套回呼,加載影像的異步操作在XMLHttpRequest訪問請求的回應回呼中實作,這樣可以讓訪問json請求結束了之后立刻去訪問影像操作,那么更進一步來假設,需要加入一個行為,在加載影像完成之后再進行操作呢(例如進行影像處理)?這樣的話我們就得再加一層回呼函式的嵌套,這樣,程式由上至下,由前往后的順序就會變成由外而內——最直觀的不便就是,"{}"層級變得多了,程式會變得難以閱讀——而這,就是所謂的“回呼地獄”了,
2??Promise實作
為了解決“回呼地獄”的問題,Promise應運而生,在之前的文章中說過,Promise的目的,是希望異步行為能像同步操作一樣遵循順序,從而避免嵌套回呼,也就是說,只要在每次的成功實作,也就是then()方法中,再次回傳新的Promise物件,就可以再次呼叫該Promise物件的then()方法,這樣異步行為也就可以像同步操作那樣,按順序組合起來了,并且這個組合是鏈式的,從前到后的,從而避免了多層嵌套:
$(function () {
function get(url) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function () {
//即使是404也會進入這個相應函式,所以需要檢測狀態
if (req.status == 200) {
//完成許諾,回傳回應文本
resolve(req.response);
} else {
//完成未完成,回傳錯誤
reject(Error(req.statusText));
}
};
// 發生錯誤時的相應函式
req.onerror = function () {
reject(Error("Network Error"));
};
// 發送請求
req.send();
});
}
function getImg(uri){
return new Promise(function(resolve, reject){
var img = new Image();
img.onload = function () {
resolve(img);
};
img.onerror = function () {
reject(Error("Load Image Error!"));
}
img.src = https://www.cnblogs.com/charlee44/archive/2021/05/03/uri;
});
}
var addressUri ="./1.json";
get(addressUri).then(function (response) {
var imgJson = JSON.parse(response);
return getImg(imgJson[0]);
}, function (error) {
console.error("Failed!", error);
}).then(function(img){
$(img).appendTo($('#container'));
}, function(error){
console.error("Failed!", error);
});
});
??參考
- JavaScript Promises: An introduction
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/282542.html
標籤:其他
上一篇:Vue.js組件的使用
下一篇:Vue.js組件的使用
