Promise已经深入到前端开发中的各个环节了,异步操作,api接口请求避免不了!Promise 是异步编程的一种解决方案,
比传统的解决方案——回调函数和事件——更合理和更强大!
promise实现红绿灯效果
const promise = new Promise((resolve, reject) => {
if (true) {
resolve("ok");
}
});
promise.then((res) => {
console.log(res);
});
function timeout(ms) {
return new Promise((resolve, reject) => {
//setTimeout第三个参数是第一个方法的参数
setTimeout(resolve, ms, "done2222");
});
}
timeout(1000).then((res) => {
console.log(res, "res");
});
/**
* ok
done2222 res
*/
改成通用方法
function delay(ms, value) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, value);
});
}
async function showColor() {
const res1 = await delay(1000, "红灯");
console.log(res1);
const res2 = await delay(2000, "黄灯");
console.log(res2);
const res3 = await delay(3000, "绿灯");
console.log(res3);
// showColor();
}
showColor();
Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数, 将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出
let promise = new Promise((resolve, reject) => {
console.log("Promise");
resolve();
});
promise.then(() => {
console.log("resolved");
});
console.log("HI");
/**
* Promise
* HI
* resolved
*/
function loadImageAsync(url) {
return new Promise((resolve, reject) => {
const image = new Image();
image.onload = function () {
resolve(image);
};
image.onerror = function () {
reject(new Error("Could not load image at " + url));
};
image.src = url;
});
}
封装原生ajax
const getJSON = function (url) {
const promise = new Promise((resolve, reject) => {
const handler = function (data) {
if (this.readyState != 4) return;
if (this.status === 200 && this.readyState === 4) {
//console.log(this, "8888");
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
const client = new XMLHttpRequest();
client.open("get", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
});
return promise;
};
Promise中返回一个promise
const p1 = new Promise((resolve, reject) => {
setTimeout(reject, 2000, new Error("fail"));
});
const p2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, p1);
});
p2.then((res) => console.log(res)).catch((error) => {
console.log(error);
});
//(node:24044) UnhandledPromiseRejectionWarning: Error: fail
//浏览器中 => Error: fail
.catch方法的作用与优势
new Promise((resolve, reject) => {
return resolve(1);
console.log(2);
}).then((res) => {
console.log(res);
});
const getJSON = function (url) {
const promise = new Promise((resolve, reject) => {
const handler = function (data) {
if (this.readyState != 4) return;
if (this.status === 200 && this.readyState === 4) {
console.log(this, "8888");
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
const client = new XMLHttpRequest();
client.open("get", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
});
return promise;
};
getJSON("./data.json")
.then((res) => {
return getJSON(res.url);
})
.then(
(data) => {
throw new Error("fail22");
console.log(data, "data");
},
(err) => console.log("rejected", err)
);
.catch((err) => console.log("rejected2222", err));
getJSON("./data.json")
.then((res) => {
throw new Error("fail22");
return getJSON(res.url);
})
.then((data) => {
console.log(data, "data");
})
.catch((err) => console.log("rejected", err));
const datas = [1, 2, 3].map((ele) => {
return getJSON("./data" + ele + ".json");
});
// console.log(datas, "data");
Promise.all(datas)
.then((res) => {
console.log(res, "datas");
})
.catch((err) => {
console.log(err, "catch");
});
/**
* promises是包含 3 个 Promise 实例的数组,只有这 3 个实例的状态都变成fulfilled,
* 或者其中有一个变为rejected,才会调用Promise.all方法后面的回调函数。
*/
promise.all的使用与特性
const p1 = new Promise((resolve, reject) => {
resolve("hello");
})
.then((res) => res)
.catch((value) => value);
const p2 = new Promise((resolve, reject) => {
throw new Error("报错了");
})
.then((res) => res)
.catch((value) => value);
Promise.all([p1, p2])
.then((res) => console.log(res))
.catch((e) => console.log(e));
promise实现异步加载图片
<div id="box"></div>
<script>
//加载一张图片
loadImageAsync(
"https://triassit.oss-cn-shenzhen.aliyuncs.com/1502096626409238530/form/1669167445413228545/40c94992-3f2b-42e6-9b90-0dc8cb08579e/76933eb2-9aae-4ed2-bb6a-b56be4224a1d.jpg?Expires=1689737677&OSSAccessKeyId=LTAI5tEA4v7LMXeCfNXXikQq&Signature=I2Rtb%2BmGzw2ESi%2BM6yQ%2F5kZ65RA%3D&response-content-disposition=attachment"
).then((res) => {
console.log(res, "loadImageAsync");
// document.querySelector('#box').appendChild(res)
});
//加载多张图片
const imgUrls = ["https://triassit.oss-cn-shenzhen.aliyuncs.com/1502096626409238530/form/1669167445413228545/40c94992-3f2b-42e6-9b90-0dc8cb08579e/76933eb2-9aae-4ed2-bb6a-b56be4224a1d.jpg?Expires=1689737677&OSSAccessKeyId=LTAI5tEA4v7LMXeCfNXXikQq&Signature=I2Rtb%2BmGzw2ESi%2BM6yQ%2F5kZ65RA%3D&response-content-disposition=attachment",
"https://triassit.oss-cn-shenzhen.aliyuncs.com/1502096626409238530/form/1669167445413228545/40c94992-3f2b-42e6-9b90-0dc8cb08579e/381ffe18-0d10-452b-93a8-07b4b1f4f8e1.jpg?Expires=1689737677&OSSAccessKeyId=LTAI5tEA4v7LMXeCfNXXikQq&Signature=k55etNrEXifvOXAxWpsJnjZnZak%3D&response-content-disposition=attachment"]
const arrs = imgUrls.map(async url => {
return await loadImageAsync(url)
})
// console.log(arrs)
const ret = Promise.all(arrs)
// console.log(ret,'Promise')
ret.then(res => {
console.log(res,'Promise')
res.forEach(item => document.querySelector('#box').appendChild(item))
})
几个请求的json数据
data1.json
{
"name":"好好好",
"age":100,
"url":"data2.json"
}
data2.json
{
"addr":"广州"
}
data3.json
{
"sex":"男"
}