JavaScript中Promise的使用方法實例
前言
我還記得我剛開始學(xué)習(xí)JavaScript的Promise很多概念都不懂很"懵逼", 現(xiàn)在已經(jīng)工作有小半年時間了, 整理整理筆記和個人在工作中的使用情況, 寫個文章記錄一下(PS只記錄怎么使用, 原理太深奧功力不夠), 如果有不對的地方前輩勿噴??
Promise簡介
Promise也稱期約, 是ES6推出的一個異步解決方案, 可以有效的解決異步函數(shù)嵌套太深("回調(diào)地獄")的問題
什么是回調(diào)地獄?
假設(shè)有個需求需要獲取用戶的指定數(shù)據(jù)用戶數(shù)據(jù)3這個數(shù)據(jù)依賴用戶數(shù)據(jù)2而用戶數(shù)據(jù)2又依賴于用戶數(shù)據(jù)1, 所以正確的數(shù)據(jù)獲取數(shù)據(jù)順序為: 用戶數(shù)據(jù)1-->用戶數(shù)據(jù)2-->用戶數(shù)據(jù)3, 模擬一下使用回調(diào)函數(shù)的寫法如下:
Node接口:
const router = require('express').Router();
const data1 = { data: "用戶數(shù)據(jù)1" };
router.get('/testData1', (req, res) => {
res.json(data1);
})
const data2 = { data: "用戶數(shù)據(jù)1,用戶數(shù)據(jù)2" };
router.get('/testData2', (req, res) => {
if (req.query.data === data1.data) {
res.json(data2);
} else {
res.status(401).json("參數(shù)錯誤");
}
})
router.get('/testData3', (req, res) => {
if (req.query.data === data2.data) {
res.json({ data: "用戶數(shù)據(jù)1,用戶數(shù)據(jù)2,用戶數(shù)據(jù)3" });
} else {
res.status(401).json("參數(shù)錯誤");
}
})
module.exports = router;前端請求代碼:
// 簡單封裝的 XMLHttpRequest 請求函數(shù)
const baseUrl = "http://localhost:8888/test";
const request = (url, cb) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', baseUrl + url);
xhr.send();
xhr.onreadystatechange = () => {
const { readyState, status, response } = xhr;
if (readyState === 4) {
if (status >= 200 && status <= 299) {
cb(JSON.parse(response));
} else {
throw new Error(response);
}
}
}
}
// 因為下一個請求需要上一個請求的數(shù)據(jù)所以需要一個回調(diào)函數(shù)嵌套一個回調(diào)函數(shù)
request("/testData1", res1 => {
console.log(res1); // => {data: '用戶數(shù)據(jù)1'}
request(`/testData2?data=${res1.data}`, res2 => {
console.log(res2); // => {data: '用戶數(shù)據(jù)1,用戶數(shù)據(jù)2'}
request(`/testData3?data=${res2.data}`, res3 => {
console.log("需求需要的數(shù)據(jù)", res3); // => 需求需要的數(shù)據(jù) {data: '用戶數(shù)據(jù)1,用戶數(shù)據(jù)2,用戶數(shù)據(jù)3'}
// ....
})
})
})這個代碼看著就頭大, 如果需求復(fù)雜的話, 我只能用一張圖表示(這張圖片我也不記得從哪里保存的忘了??)

這種一個回調(diào)嵌套一個回調(diào)的代碼可讀性和可維護性都很差, 被稱為"回調(diào)地獄", 而Promise的出現(xiàn)就可以很好的解決這個問題
Promise的特點
Promise對象有一個狀態(tài), 這個狀態(tài)不受外界影響, 狀態(tài)一共分為3種:
- Pending狀態(tài) (進行中(又稱待定)) 初始狀態(tài)
- Fulfilled狀態(tài) (成功(又稱兌現(xiàn)))
- Rejected狀態(tài)(失敗(又稱拒絕))
關(guān)于Promise的狀態(tài)叫法下文統(tǒng)一使用成功,失敗
一旦Promise對象的狀態(tài)改變(成功或失敗)就不會再變, 是單向的:
Pending(進行中) -> Fulfilled(成功)
Pending(進行中) -> Rejected(失敗)
創(chuàng)建Promise實例
創(chuàng)建Promise實例需要newPromise構(gòu)造函數(shù), 該構(gòu)造函數(shù)接受一個函數(shù)(處理器函數(shù))作為參數(shù), 該函數(shù)會收到兩個參數(shù), 這兩個參數(shù)分別是resolve和reject(叫什么都行一般還是要語義化名稱)它們是兩個函數(shù), 不用自己實現(xiàn)就可以使用, 如下:
const p = new Promise((resolve, reject) => {
})
console.log(p);
可以看到這個狀態(tài)默認是Pending(進行中)
resolve和reject這兩個參數(shù)(函數(shù))可以在處理器函數(shù)里面調(diào)用(可以傳遞參數(shù)), 這樣將會改變 Promise 對象的狀態(tài):
const p = new Promise((resolve, reject) => {
resolve();
})
console.log(p);
當調(diào)用resolve函數(shù)時會將Priomise對象的狀態(tài)修改為Fulfilled(成功), 調(diào)用reject函數(shù)則會將狀態(tài)修改為Rejected(失敗)
then方法
Promise實例的then方法, 可以接受兩個參數(shù)(都是函數(shù))分別指定Primise實例里面狀態(tài)(成功或失敗)改變時調(diào)用的回調(diào)函數(shù)(并且Promise的then方法是異步的微任務(wù)):
const p = new Promise((resolve, reject) => {
// 將p的狀態(tài)修改為成功
resolve();
})
console.log("同步代碼");
p.then(
() => {
console.log("成功的回調(diào)");
},
() => {
console.log("失敗的回調(diào)");
}
)結(jié)果如下:

反之調(diào)用reject函數(shù)就會觸發(fā)then方法的第二個回調(diào)函數(shù), 如果將resolve函數(shù)和reject函數(shù)都調(diào)用只會生效最先調(diào)用的(因為狀態(tài)時單向的嘛)
resolve 和 reject 的參數(shù)傳遞
經(jīng)過上面的測試我們知道resolve和reject這兩個函數(shù)是可以修改狀態(tài)并且觸發(fā)Promise的then方法的回調(diào)函數(shù)的, 那么是函數(shù)就可以傳遞參數(shù), 這個參數(shù)會被傳遞給對應(yīng)的then方法的回調(diào)函數(shù)接收到:
const p = new Promise((resolve, reject) => {
// 將p的狀態(tài)修改為成功, 并且傳遞一個參數(shù)
resolve("ok");
})
console.log("同步代碼");
p.then(
// 這里接收 resolve 函數(shù)傳遞的參數(shù)
res => {
console.log("成功的回調(diào)", res);
},
// 這里接收 reject 函數(shù)傳遞的參數(shù)
err => {
console.log("失敗的回調(diào)");
}
)結(jié)果如下:

then()鏈式調(diào)用
了解完then方法以后我們就可以稍微修改一下一開始最上面的需求:
// 請求函數(shù)使用 Promise 封裝
const baseUrl = "http://localhost:8888/test";
const request = (url) => {
// 返回一個Promise實例
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', baseUrl + url);
xhr.send();
xhr.onreadystatechange = () => {
const { readyState, status, response } = xhr;
if (readyState === 4) {
if (status >= 200 && status <= 299) {
const res = JSON.parse(response);
// 修改狀態(tài)為成功并且把響應(yīng)傳遞過去
resolve(res);
} else {
// 修改狀態(tài)為失敗也把響應(yīng)傳遞過去
reject(response);
}
}
}
})
}
// 使用then方法
request("/testData1").then(
res1 => {
console.log(res1); // {data: '用戶數(shù)據(jù)1'}
request(`/testData2?data=${res1.data}`).then(
res2 => {
console.log(res2); // {data: '用戶數(shù)據(jù)1,用戶數(shù)據(jù)2'}
request(`/testData3?data=${res2.data}`).then(
res3 => {
console.log("需求需要的數(shù)據(jù)", res3); // => 需求需要的數(shù)據(jù) {data: '用戶數(shù)據(jù)1,用戶數(shù)據(jù)2,用戶數(shù)據(jù)3'}
}
)
}
)
}
)寫完以后發(fā)現(xiàn)好像還不如使用回調(diào)函數(shù)的方式寫, 看到這里好像Promise還是不能很好的解決回調(diào)嵌套的問題; 換個思路如果我們在then方法中再返回一個Promise實例, 那么不就又可以調(diào)用then方法了嗎? 代碼中測試一下:
const p1 = new Promise((resolve, reject) => {
resolve("p1數(shù)據(jù)");
})
// 這里的p2就是p1.then方法成功回調(diào)里面返回的p2
const p2 = p1.then(
// 這里的res1參數(shù)就是p1的處理器函數(shù)中調(diào)用 resolve("p1數(shù)據(jù)") 傳遞的參數(shù)
res1 => {
console.log(res1); // p1數(shù)據(jù)
// 這里新建一個新的Promise實例, 記作p2
const p2 = new Promise((resolve, reject) => {
// 0.5s后修改狀態(tài)
setTimeout(() => {
resolve(res1 + ",p2數(shù)據(jù)");
}, 500);
})
// 將p2返回
return p2;
}
)
const p3 = p2.then(
res2 => {
console.log(res2); // p1數(shù)據(jù),p2數(shù)據(jù)
// 這里和上面的同理
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(res2 + ",p3數(shù)據(jù)");
}, 500);
})
return p3;
}
)
p3.then(
res3 => {
console.log(res3); // p1數(shù)據(jù),p2數(shù)據(jù),p3數(shù)據(jù)
}
)發(fā)現(xiàn)可行后, 把需求代碼再修改一下:
// 這里的p1就是 request("/testData1") 返回的Promise實例
const p1 = request("/testData1");
// 這里的p2就是p1.then方法成功回調(diào)返回的p2
const p2 = p1.then(
res1 => {
console.log(res1); // {data: '用戶數(shù)據(jù)1'}
// 再調(diào)用request方法將其返回的Promise實例記作p2
const p2 = request(`/testData2?data=${res1.data}`);
// 將p2返回
return p2;
}
)
const p3 = p2.then(
res2 => {
console.log(res2); // {data: '用戶數(shù)據(jù)1,用戶數(shù)據(jù)2'}
// 這里和上面的同理
const p3 = request(`/testData3?data=${res2.data}`);
return p3;
}
)
p3.then(
res3 => {
console.log("需求需要的數(shù)據(jù)", res3); // 需求需要的數(shù)據(jù) {data: '用戶數(shù)據(jù)1,用戶數(shù)據(jù)2,用戶數(shù)據(jù)3'}
}
)需求實現(xiàn)是實現(xiàn)了, 就是代碼有點冗余, 可以精簡一下, 如下:
request("/testData1").then(
res1 => {
console.log(res1); // {data: '用戶數(shù)據(jù)1'}
// 這里直接返回 request方法的返回值Promise實例
return request(`/testData2?data=${res1.data}`);
}
).then(
// 這個成功回調(diào)時上一個then方法返回的Promise實例的成功回調(diào)
res2 => {
console.log(res2); // {data: '用戶數(shù)據(jù)1,用戶數(shù)據(jù)2'}
// 同理
return request(`/testData3?data=${res2.data}`);
}
).then(
// 同理
res3 => {
console.log("需求需要的數(shù)據(jù)", res3); // 需求需要的數(shù)據(jù) {data: '用戶數(shù)據(jù)1,用戶數(shù)據(jù)2,用戶數(shù)據(jù)3'}
}
)上面的代碼格式就像鏈條一樣所以又被稱為"鏈式調(diào)用"
then()的返回值
經(jīng)過上面的代碼測試, then方法除了返回Promise對象外還可以返回其他任意的值, 返回會被轉(zhuǎn)換為Promise對象, 內(nèi)部的狀態(tài)視返回值而定:
const p1 = new Promise(resolve => resolve());
p1.then(() => {
// 這里相當于是 return undefined
}).then(
res1 => {
console.log(res1); // undefined
return "hello";
}
).then(
res2 => {
console.log(res2); // hello
return { name: "張三" };
}
).then(
res3 => {
console.log(res3); // { name: "張三" }
// 返回錯誤對象該Promise對象的狀態(tài)也是成功
return new Error("error object");
}
).then(
res4 => {
console.log(res4 instanceof Error); // true
console.log(res4.message); // error object
// 拋出一個錯誤則該Promise對象的狀態(tài)是失敗
throw "thorw error";
}
).then(
() => { },
err => {
console.log(err); // thorw error
}
)catch方法
上面使用then方法的鏈式調(diào)用可以解決回調(diào)嵌套太深的問題, 但是還沒處理請求之間的失敗回調(diào)處理, then方法的第二個回調(diào)就是指定失敗的回調(diào), 但是一般都不使用這個回調(diào)來處理錯誤, 而是使用catch方法來失敗, 使用格式如下:
p1.then(
// ...
).then(
// ...
).catch(err => { // 這個catch可以捕獲這一條調(diào)用鏈上的錯誤
// 處理錯誤
})finally方法
除了catch方法那自然就有finally方法, finally方法和try...catch...finally中的finally是一樣的作用, 使用格式如下:
p.then(
// ...
).then(
// ...
).catch(err => { // 這個catch方法可以捕獲這一條調(diào)用鏈上的錯誤
// 處理錯誤
}).finally(() => { // 無論成功還是失敗這個finally中指定的回調(diào)都會執(zhí)行
// 清除loading, 重置狀態(tài)...
})Promise的方法
Promise.resolve()
立即返回一個狀態(tài)是成功(Fulfilled) 的 Promise 對象, 可以傳遞參數(shù), 參數(shù)會被其返回的Promise實例的then方法的回調(diào)(異步微任務(wù))接受到:
const p = Promise.resolve("Promise.resolve");
p.then(res => console.log(res)); // Promise.resolve也可以利用Promise.resolve()來創(chuàng)建一個微任務(wù):
console.log("同步代碼");
setTimeout(() => console.log("setTimeout"), 0);
const p = Promise.resolve("Promise.resolve");
p.then(res => console.log(res));結(jié)果如下:

Promise.reject()
和Promise.resolve()一樣不過返回的狀態(tài)是失敗(Rejected) 的Promise對象(同樣是微任務(wù))
console.log("同步代碼");
setTimeout(() => console.log("setTimeout"), 0);
const p = Promise.reject("Promise.reject");
p.then().catch(err => console.log("Promise.reject"));Promise.all()
Promise.all接收一個Promise的iterable類型(就是可迭代對象里面存放著Promise實例, Array, Map, Set都屬于ES6的iterable類型), Promise.all 會等待所有的Promise對象都完成(或第一個失敗) , 根據(jù)給定的參數(shù)返回不同的參數(shù)
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p1 data"), 500);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p2 data"), 1000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p3 data"), 1500);
})
// 依次打印數(shù)據(jù)
p1.then(res => console.log(res)); // 0.5s 后打印 p1 data
p2.then(res => console.log(res)); // 1.0s 后打印 p2 data
p3.then(res => console.log(res)); // 1.5s 后打印 p3 data
const proArray = [p1, p2, p3];
Promise.all(proArray).then(resList => {
console.log(resList); // 1.5s后打印數(shù)據(jù) ['p1 data', 'p2 data', 'p3 data']
}).catch(err => {
// 如果在`Promise.all`方法中出現(xiàn)了失敗的狀態(tài), 那么這個參數(shù)會是這個失敗狀態(tài)返回的參數(shù)(如果有的話)
console.error("error: ", err);
})利用Promise.all()方法的特定可以用于同時發(fā)送多個請求, 如下例子:
Node接口:
const getRandom = () => Math.random() * 9 + 1;
router.get('/testData4', (req, res) => {
let n = req.query.n;
const random = getRandom();
// 定時器模擬接口響應(yīng)時間差
setTimeout(() => {
res.json(`第${++n}個請求${random}`);
}, random * 50);
});前端發(fā)送多個請求:
const proArray = [];
for (let i = 0; i < 10; i++) {
// 將10個請求方法返回的Promsie對象添加到proArray數(shù)組中
proArray.push(request(`/testData4?n=${i}`));
}
Promise.all(proArray).then(resList => {
for (const res of resList) {
// 每個請求的返回結(jié)果
console.log(res);
}
})Promise.allSettled()
Promise.allSettled()方法和Promise.all()很類似只不過是接受的期約對象無論是成功還是失敗都會觸發(fā)then方法的成功回調(diào), 每個期約都會返回一個對象status屬性表示狀態(tài), value表示成功回調(diào)的值, 如果狀態(tài)是失敗的那么失敗回調(diào)的值存儲在reason屬性中:
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p1 data"), 500);;
})
const p2 = new Promise((resolve, reject) => {
// p2的Promise實例的狀態(tài)修改為失敗
setTimeout(() => reject("p2 err"), 1000);
})
const proArray = [p1, p2];
Promise.allSettled(proArray).then(resList => {
console.log(resList); // (2) [{…}, {…}]
for (const res of resList) {
const { status, value, reason } = res;
if (reason) {
console.log(`失敗: ${status}, 原因是: ${reason}`); // 失敗: rejected, 原因是: p2 err
} else {
console.log(`成功: ${status}, 數(shù)據(jù)是: ${value}`); // 成功: fulfilled, 數(shù)據(jù)是: p1 data
}
}
}).catch(err => {
// 這里不會捕獲p2的失敗的回調(diào)
console.error("error: ", err);
})Promise.race()
Promise.race()和Promise.all()類似, 都接收一個可以迭代的參數(shù), 但是不同之處是
Promise.race()的狀態(tài)變化不是受全部參數(shù)的狀態(tài)影響, 一旦迭代器中的某個Promise解決或拒絕,返回的 Promise就會解決或拒絕
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p1 data"), 500);;
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => reject("p2 err"), 1000);
})
const proArray = [p1, p2];
Promise.race(proArray).then(res => {
console.log(res); // p1 data
}).catch(err => {
console.error(err);
})async 和 await
async函數(shù)函數(shù)
async函數(shù)函數(shù)就是使用async關(guān)鍵字聲明的函數(shù)(也叫異步函數(shù)), async函數(shù)和普通的函數(shù)使用沒有什么區(qū)別:
// 函數(shù)聲明
async function asyncFn1() {
console.log("asyncFn1");
}
// 函數(shù)表達式
const asyncFn2 = async () => {
console.log("asyncFn2");
}
asyncFn1();
asyncFn2();
// 立即調(diào)用
(async () => {
console.log("asyncFn3");
})();await
await操作符用于等待一個Promise對象, 它只能在async function中使用, 使用async+await可以將異步的代碼"變"的跟同步的一樣:
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("data");
}, 1000);
});
// async 函數(shù)
async function asyncFn() {
console.log("asyncFn函數(shù)開始執(zhí)行");
// await 會等待右邊的Promise對象的狀態(tài)變成功后返回其值
const res = await p;
console.log(res); // data
console.log("asyncFn函數(shù)執(zhí)行完了");
}
// 調(diào)用
asyncFn();上面的代碼會先輸出"asyncFn函數(shù)開始執(zhí)行"后, 等待1s左右輸出"data", 然后再輸出"asyncFn函數(shù)執(zhí)行完了"
注意: 異步函數(shù)不會阻塞主線程的執(zhí)行, 它是異步的:
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("data");
}, 1000);
});
// async 函數(shù)
async function asyncFn() {
console.log("asyncFn函數(shù)開始執(zhí)行");
const res = await p;
console.log(res);
console.log("asyncFn函數(shù)執(zhí)行完了");
}
console.log("hello");
asyncFn();
console.log("javascript");等待大約1s后上面的代碼執(zhí)行結(jié)果如下:

根據(jù)上面的代碼執(zhí)行結(jié)果, 我們發(fā)現(xiàn)異步函數(shù)內(nèi)await關(guān)鍵字會等待其右邊的Promise對象的返回值, 等待結(jié)束后, 后面的代碼才會被執(zhí)行, 利用這個特性我們可以在JavaScript中可以實現(xiàn)類似Java的Thread.sleep()方法, 如下:
const sleep = async time => new Promise(resolve => setTimeout(resolve, time));
(async () => {
console.log("1");
await sleep(1000);
console.log("2");
await sleep(500);
console.log("2.5");
})();了解完async和await的使用后我們可以使用異步函數(shù)再來完成我們一開始的需求:
// 請求函數(shù)使用 Promise 封裝
const baseUrl = "http://localhost:8888/test";
const request = (url) => {
// 返回一個Promise實例
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', baseUrl + url);
xhr.send();
xhr.onreadystatechange = () => {
const { readyState, status, response } = xhr;
if (readyState === 4) {
if (status >= 200 && status <= 299) {
const res = JSON.parse(response);
// 修改狀態(tài)為成功并且把響應(yīng)傳遞過去
resolve(res);
} else {
// 修改狀態(tài)為失敗也把響應(yīng)傳遞過去
reject(response);
}
}
}
})
}
async function asyncFn() {
const res1 = await request("/testData1");
console.log(res1); // {data: '用戶數(shù)據(jù)1'}
const res2 = await request(`/testData2?data=${res1.data}`);
console.log(res2); // {data: '用戶數(shù)據(jù)1,用戶數(shù)據(jù)2'}
const res3 = await request(`/testData3?data=${res2.data}`);
console.log(res3); // {data: '用戶數(shù)據(jù)1,用戶數(shù)據(jù)2,用戶數(shù)據(jù)3'}
}
asyncFn();可以看到使用async和await來發(fā)送網(wǎng)絡(luò)請求寫的代碼很簡潔, 也很直觀
異步函數(shù)的錯誤處理
異步函數(shù)的異常處理可以使用try...catch和catch處理:
try...catch
async function asyncFn() {
let res1, res2, res3;
try {
res1 = await request("/testData1");
try {
if (res1?.data) {
res2 = await request(`/testData2?data=${res1.data}`);
}
try {
if (res2?.data) {
res3 = await request(`/testData3?data=${res2.data}`);
}
} catch (error) {
// 處理res3 error
}
} catch (error) {
// 處理res2 error
}
} catch (error) {
// 處理res3 error
}
}catch
async function asyncFn() {
const res1 = await request("/testData1")
.catch(err => {
// 處理res1 error
});
if (res1?.data) {
const res2 = await request(`/testData2?data=${res1.data}`)
.catch(err => {
// 處理res2 error
});
if (res2?.data) {
const res3 = await request(`/testData3?data=${res2.data}`)
.catch(err => {
// 處理res3 error
});
}
}
}異步函數(shù)同樣適用于Promise的一些靜態(tài)方法
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p1 data"), 500);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p2 data"), 1000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p3 data"), 1500);
})
const proArray = [p1, p2, p3];
async function asyncFn() {
const list = await Promise.all(proArray);
console.log(list); // ['p1 data', 'p2 data', 'p3 data']
}
asyncFn();for await...of
一個數(shù)組中存儲多個Promise對象我們可以通過Promise.all獲取或者通過循環(huán)來等待其返回值, 我們使用循環(huán):
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p1 data"), 500);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p2 data"), 1000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => resolve("p3 data"), 1500);
})
const proArray = [p1, p2, p3];
async function asyncFn() {
for (const pro of proArray) {
// 這里不要忘記 await
const res = await pro;
console.log(res);
}
}
asyncFn();ES9開始有一個新語法就是for await..of可以自動等待每次循環(huán)的項
async function asyncFn() {
for await (const item of proArray) {
console.log(item);
}
}
asyncFn();參考:
- MDN Promise
- MDN async
- MDN for await...of
- JavaScript權(quán)威指南
- 阮一峰ES6入門之promise
總結(jié)
到此這篇關(guān)于JavaScript中Promise使用的文章就介紹到這了,更多相關(guān)JS Promise的使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS獲取url參數(shù),JS發(fā)送json格式的POST請求方法
下面小編就為大家分享一篇JS獲取url參數(shù),JS發(fā)送json格式的POST請求方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03
利用百度echarts實現(xiàn)圖表功能簡單入門示例【附源碼下載】
這篇文章主要介紹了利用百度echarts實現(xiàn)圖表功能簡單,結(jié)合簡單示例形式分析了echarts插件的圖標繪制功能相關(guān)實現(xiàn)技巧,并附帶源碼供讀者下載參考,需要的朋友可以參考下2019-06-06
JS實現(xiàn)將對象轉(zhuǎn)化為數(shù)組的方法分析
這篇文章主要介紹了JS實現(xiàn)將對象轉(zhuǎn)化為數(shù)組的方法,結(jié)合實例形式分析了javascript操作及轉(zhuǎn)換json數(shù)組相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2019-01-01

