36、ajax
<script>
const getJSON = function (url) {
return new Promise((resolve, reject) => {
const xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xhr.open('GET', url, false);
xhr.setRequestHeader('Accept', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return;
if (xhr.status === 200 || xhr.status === 304) {
resolve(xhr.responseText);
} else {
reject(new Error(xhr.responseText));
}
}
xhr.send();
})
}
</script>
37、再次手写Promise
<!DOCTYPE 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>Document</title>
<style>
img {
width: 200px;
height: 200px;
display: block;
margin-bottom: 20px;
}
</style>
</head>
<body>
<script>
const resolvePromise = (promise2, x, resolve, reject) => {
if (promise2 === x) return reject(new TypeError("Chaining cycle detected for promise #<Promise>"));
if (x instanceof Promise) {
x.then(res => {
resolve(res)
}, err => {
reject(err)
})
} else {
resolve(x);
}
}
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn());
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
let promise2 = new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
setTimeout(() => {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
}, 0)
} else if (this.state === 'rejected') {
setTimeout(() => {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
}, 0)
} else {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
}, 0)
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
}, 0)
});
}
});
return promise2;
}
}
const p1 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(100)
}, 1000)
})
p1.then((res) => {
console.log(res);
})
const p2 = new MyPromise((resolve, reject) => {
resolve(500)
})
p2.then(res => {
console.log(res);
return 200;
}).then(res => {
console.log(res)
})
const p3 = new MyPromise((resolve, reject) => {
resolve(500)
})
p3.then(res => {
console.log(res);
return new Promise((resolve, reject) => {
resolve(100)
});
}).then(res => {
console.log(res)
})
</script>
</body>
</html>