回調函數javascript
// 假若有兩個函數f1和f2 後者等待前者的執行結果
// 若是f1是一個很耗時的任務,能夠考慮改寫f1,把f2寫成f1的回調函數
function f2(c) {
console.log(c, 'hehe');
}
function f1(callback) {
setTimeout(function() {
// f1任務代碼
console.log('f1執行完');
callback('f2開始執行', 'hehe');
}, 1000);
}
f1(f2);
複製代碼
事件監聽css
f1.on('done', f2);
複製代碼
發佈/訂閱html
function Event() {
// 存儲不一樣的事件類型對應不一樣的處理函數,保證後續emmit能夠執行。
this.cache = {};
}
// 綁定事件
Event.prototype.on = function(type, handle) {
if(!this.cache[type]) {
this.cache[type] = [handle];
}else {
this.cache[type].push(handle);
}
}
// 事件觸發
Event.prototype.emmit = function() {
var type = arguments[0],
arg = [].slice.call(arguments, 1);
for(var i = 0; i < this.cache[type].length; i++) {
this.cache[type][i].apply(this, arg);
if(this.cache[type][i].flag) {
this.cache[type].splice(i, 1);
if(this.cache[type][i].flag) {
this.cache[type].splice(i, 1);
}
}
}
}
// 解除某個事件類型
Event.prototype.empty = function(type) {
this.cache[type] = [];
}
// 解除某個事件
Event.prototype.remove = function(type, handle) {
this.cache[type] = this.cache[type].filter((ele) => ele != handle);
}
// 綁定一次事件
Event.prototype.once = function(type, handle) {
if(!this.cache[type]) {
this.cache[type] = [];
}
// 作標記
handle.flag = true;
this.cache[type].push(handle);
}
function detail1(time) {
console.log('overtime1' + time);
}
function detail2(time) {
console.log('overtime2' + time);
}
var oE = new Event();
oE.on('over', detail1);
oE.on('over', detail2);
oE.emmit('over', '2019-11-11');
oE.remove('over', detail2);
oE.emmit('over', 'second-11-11');
複製代碼
Promise對象java
function MyPromise(executor) {
var self = this;
self.status = 'pending';
self.resolveValue = null;
self.rejectReason = null;
self.resolveCallBackList = [];
self.RejectCallBackList = [];
function resolve(value) {
if(self.status === 'pending') {
self.status = 'Fulfilled';
self.resolveValue = value;
self.resolveCallBackList.forEach(function(ele) {
ele();
});
}
}
function reject(reason) {
if(self.status === 'pending') {
self.status = 'Rejected';
self.rejectReason = reason;
self.RejectCallBackList.forEach(function(ele) {
ele();
})
}
}
try {
executor(resolve, reject);
}catch(e) {
reject(e);
}
}
function ResolutionReturnPromise(nextPromise, returnValue, res, rej) {
if(returnValue instanceof MyPromise) {
returnValue.then(function() {
res(val);
}, function(reason) {
rej(reason);
})
}else {
res(returnValue);
}
}
MyPromise.prototype.then = function(onFulfilled, onRejected) {
if(!onFulfilled) {
onFulfilled = function(val) {
return val;
}
}
if(!onRejected) {
onRejected = function(reason) {
throw new Error(reason);
}
}
var self = this;
var nextPromise = new MyPromise(function(res, rej) {
if(self.status === 'Fulfilled') {
setTimeout(function() {
try {
var nextResolveValue = onFulfilled(self.resolveValue);
ResolutionReturnPromise(nextPromise, nextResolveValue, res, rej);
}catch(e) {
rej(e);
}
}, 0);
}
if(self.status === 'Rejected') {
setTimeout(function() {
try{
var nextResolveValue = onRejected(self.rejectReason);
ResolutionReturnPromise(nextPromise, nextRejectValue, res, rej);
}catch(e) {
rej(e);
}
})
}
if(self.status === 'pending') {
self.resolveCallBackList.push(function() {
setTimeout(function() {
try {
var nextResolveValue = onFulfilled(self.resolveValue);
ResolutionReturnPromise(nextPromise, nextResolveValue, res, rej);
}catch(e) {
rej(e);
}
}, 0)
})
}
})
return nextPromise;
}
MyPromise.race = function(promiseArr) {
return new Promise(function(resolve, reject) {
promiseArr.forEach(function(promise, index) {
promise.then(resolve, reject);
})
})
}
複製代碼
function AJAX(json) {
var url = json.url,
method = json.method,
flag = json.flag,
data = json.data,
callBack = json.callBack,
xhr = null;
// 1. 建立異步對象
if(window.XMLHttpRequest) {
// 通常主流瀏覽器支持這個
xhr = new window.XMLHttpRequest();
}else {
// IE6如下用這個
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
// 2. 讓異步對象監聽接收服務器的響應數據
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
// 數據已經可用了
callBack(xhr.responseText);
}
}
// 創建對服務器的調用
if(method === 'get') {
url += '?' + data + new Data().getTime();
// 3. 設置請求方式
xhr.open('get', url, flag);
xhr.send();
}else {
xhr.open('post', url, flag);
// 4. 設置請求頭
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 5. 設置請求體
xhr.send(data);
}
}
複製代碼
// 這樣能層層回調的事情,你會發現要寫多個回調函數,一堆.then不夠優雅,
// 有沒有寫法寫起來像同步很優雅,最後也是經過異步的方式來搞定層層回調的結果。
function readFile(path) {
return new Promise((res, rej) => {
fs.readFile(path, 'utf-8', (err, data) => {
if(err) {
rej(err);
}else {
res(data);
}
})
})
};
readFile('https://api.github.com/users/superman66')
.then((val) => {
return readFile(val);
}, () => {}).then((val) => {
return readFile(val);
})
.then((val) => {
console.log(val);
});
// async寫法
async function read(url) {
let val1 = await readFile(url);
let val2 = await readFile(val1);
let val3 = await readFile(val2);
}
read('https://api.github.com/users/superman66')
.then((val) => console.log(val));
複製代碼
async function read(url) {
try {
let val1 = await readFile(url);
let val2 = await readFile(val1);
let val3 = await readFile(val2);
}catch(e) {
console.log(e);
}
}
readFile('./data/number.txt').then((val) => console.log(val));
複製代碼
// 以前經過解決同步併發異步的結果是使用Promise.all()去解決的,首先Promise.all()使用的時候須要傳遞多個promise對象
// 其次他是所有成功才成功,一個失敗所有失敗
Promise.all([readFile('./data/number1.txt), readFile('./readFile/number2.txt'), readFile('./data/number3.txt')])
.then((val) => console.log(val), (reason) => console.log(reason));
複製代碼
async function read1() {
let val1 = null;
try{
val1 = await readFile('./data/number1.txt');
console.log(val1);
}catch(e) {
console.log(e);
}
}
async function read2() {
let val2 = null;
try{
val2 = await readFile('./data/number2.txt');
console.log(val2);
}catch(e) {
console.log(e);
}
}
async function read3() {
let val3 = null;
try {
val3 = await readFile('./data/number3.txt');
console.log(val3);
}catch(e) {
console.log(e);
}
}
function readAll(...args) {
args.forEach((ele) => {
ele();
})
}
readAll(read1, read2, read3);
複製代碼
funtion fn(a, b, ...args) {
// ...
}
複製代碼
function fn(...[a, b, c]) {
console.log(a + b + c);
}
fn(1);
fn(1, 2, 3);
fn(1, 2, 3, 4);
複製代碼
// 把不可迭代數據變成可迭代數據
let obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
[Symbol.iterator]: function() {
let curIndex = 0;
let next = () => {
return {
value: this[curIndex],
done: this.length == ++ curIndex
}
}
return {
next
}
}
}
console.log([...obj])
for(let p of obj) {
console.log(p);
}
複製代碼
function OuterInterator() {
let curIndex = 0;
let next = () => {
return {
value: o[curIndex],
done: o.length == ++ curIndex;
}
}
return {
next
}
}
let oIt = OuterIterator(arr);
複製代碼
function loadScript(url, callback) {
var script = document.createElement('script'),
script.type = 'text/javaScript';
if(script.readyState) { // IE
if(script.onreadystatechange === 'complete' || script.onreadystatechange === 'loaded') {
callback();
}
}else { // FireFox丶Safari丶Chrome and Opera
script.onload = function() {
callback();
}
}
script.url = url;
document.head.appendChild(script);
}
複製代碼
var myLink = document.createElement('link');
myLink.rel = 'stylesheet';
'myLink.href = './index.css';
documemt.head.insertBefore(myLink, document.head.childNodes[document.head.childNodes.length - 1].nextSibling);
複製代碼
<link rel="style" href="css.style" media="jscourse" onload="this.media='all'">
複製代碼
<link rel="preload" href="sccriptfile.js" as="script">
// 要用的時候 就建立一個script標籤加載它,這個時候直接從緩存中拿到這個文件了,由於提早加載好了
var oScript = document.createElement('script');
script.src = 'index.js';
document.body.appendChild(script);
複製代碼
參考連接:www.cnblogs.com/cjx-work/p/… juejin.im/post/596e14…node