JS知识点+试题(四)异步
Promise异步
实现——加载图片
<script> function loadImage(src) { const promise = new Promise((resolve, reject) => { const img = document.createElement('img'); img.onload = function() { resolve(img); } img.onerror = function() { const error = new Error(`图片加载失败,url为:${src}`) reject(error); } img.src = src; }); return promise; } const url1 = 'https://www.keaidian.com/uploads/allimg/190424/24110307_6.jpg'; const url2 = 'https://www.keaidian.com/uploads/allimg/190424/24110307_8.jpg' loadImage(url1).then(img1 => { console.log('img1', img1) return loadImage(url2); }).then(img2 => { console.log('img2', img2); }).catch(e => { console.log('error', e); }) script>
Event Loop
async&await
async function sing(){ //return 'angle of music'; return Promise.resolve('angel of music'); } sing ().then(value =>{ console.log(value); })
await & async 必须一起使用
async function sing(){ //return 'angle of music'; console.log('1'); let two = await Promise.resolve('2'); console.log(two); console.log('3'); return Promise.resolve('angel of music'); } sing ().then(value =>{ console.log(value); })
重要作用:优化fetch语法
let hh = async()=>{ const url = ' '; try { let responses =await Promise.all( [fetch(`${url}/1/`), fetch(`${url}/2/`), fetch(`${url}/4/`)] ); let jsons = responses.map(response =>response.json()); let values = await Promise.all(jsons); values.map(value => { console. log(value.data.name); }); }catch (error){ console.log(error); } }; hh();
例题:
async function test1() { console.log('test1 begin'); // 2 const result = await test2(); // setTimeout(() => { // console.log('result', result); // console.log('test1 end'); // }, 1000); console.log('result', result); // 5 console.log('test1 end'); // 6 } async function test2() { console.log('test2'); // 3 return Promise.resolve('??????');
} console.log('script begin'); // 1 test1(); console.log('script end'); // 4
手写实现Promise
原因: 没有异步执行,设置setimeout()
原因:then 未执行
resolve reject 在循环末尾进行 setimeout()
实现链式结构
实现Promise
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
body>
<script>
class Commitment{
static PENDING = '待定';
static FULFILLED = '成功';
static REJECTED = '拒绝';
constructor(func){
this.status = Commitment.PENDING;
this.result = null;
//数组存储then的参数
this.resolveCallbacks = [];
this.rejectCallbacks = [];
try{
func(this.resolve.bind(this), this.reject.bind(this));
}catch(error){
//错误执行reject
this.reject(error);
}
}
resolve(result){
setTimeout(()=>{
if(this.status === Commitment.PENDING){
this.status=Commitment.FULFILLED;
this.result=result;
this.resolveCallbacks.forEach(callback =>{
callback(result);
});
}
});
}
reject(result){
setTimeout(()=>{
if(this.status ===Commitment.PENDING){
this.status=Commitment.REJECTED;
this.result=result;
this.rejectCallbacks.forEach(callback =>{
callback(result);
});
}
});
}
//原生Promise规定then里面两个参数如果不是函数,则忽略
then (onFULFILLED,onREJECTED){
return new Commitment((resolve,reject)=> {
//预先判断: 是函数则把原来内容重新赋值给它;不是函数改为空函数
onFULFILLED = typeof onFULFILLED === 'function' ? onFULFILLED:()=>{};
onREJECTED = typeof onREJECTED === 'function' ? onREJECTED :()=>{};
if(this.status === Commitment.PENDING){
this.resolveCallbacks.push(onFULFILLED);
this.rejectCallbacks.push(onREJECTED);
}
if(this.status === Commitment.FULFILLED){
setTimeout(()=>{
onFULFILLED(this.result);
});
}
if(this.status === Commitment.REJECTED){
setTimeout(()=>{
onREJECTED(this.result);
});
}
});
}
}
//console.log('first');
let commitment = new Commitment((resolve,reject) =>{
resolve('??????');
});
// throw new Error('hola');
console.log('second');
setTimeout(()=>{
reject('hola');
console.log('forth');
//没有??输出 then未执行
});
commitment.then(
//undefined,
//result =>{console.log(result)}, //hola
result =>{console.log(result)},
result =>{console.log(result.message)}
).then(
result =>{console.log(result)},
result =>{console.log(result.message)}
);
//实现链式结构
console.log('third');
script>
html>