promise
// 比較傳統的回調方式與promise
// 回調方法 用于請求資料(模拟)
function f(cb) {
setTimeout(function() {
cb && cb();
}, 1000);
}
f(function() {
console.log(1);
f(function() {
console.log(2);
f(function() {
console.log(3);
f(function() {
console.log(4);
f(function() {
console.log(5);
f(function() {
console.log(6);
});
});
});
});
});
});
// promise方法 用于請求資料(模拟)
function f() {
return new Promise(resolve => {
setTimeout(function() {
resolve();
}, 1000);
})
}
f()
.then(function() {
console.log(1);
return f();
})
.then(function() {
console.log(2);
return f();
})
.then(function() {
console.log(3);
});
對比回調與promise的流程控制:
一個動畫函數
//使用回調函數實作
function moveTo(el, x, y, cb) {
el.style.transform = `translate(${x}px, ${y}px)`;
setTimeout(function() {
cb && cb();
}, 1000);
}
let el = document.querySelector('div');
document.querySelector('button').addEventListener('click', e => {
moveTo(el, 100, 100, function() {
moveTo(el, 200, 200, function() {
moveTo(el, 30, 20, function() {
moveTo(el, 100, 300, function() {
moveTo(el, 130,20, function() {
moveTo(el, 0, 0, function() {
console.log('移動結束!');
});
});
});
});
});
});
});
執行個體化Promise構造函數時,傳遞一個函數,該函數有兩個參數:resolve和reject(也是兩個函數,名字可以随便取,就是兩個函數,第一個函數是用來處理成功時的回調函數,第二個函數是用來處理失敗時的回調函數)
執行個體化後的Promise對象,具有then方法,then方法用來指定上述兩個函數,resolve和reject;
then方法中也可以直接在後面繼續調用then方法,如果then方法傳回一個Promise的執行個體,那下一個then就會以上一個傳回的Promise的執行個體去執行;若沒有傳回promise執行個體,則會繼續執行,相當于将下面then方法中的代碼寫入未傳回promise執行個體的then方法中。
then()方法接收兩個參數:
1.第一個參數是狀态切換為成功時的回調,
2.第二個參數是狀态切換為失敗時的回調。如果在then中不添加參數,那麼就相當于沒有調用任何回調函數
//使用promise實作
function moveTo(el, x, y) {
return new Promise(resolve => {
el.style.transform = `translate(${x}px, ${y}px)`;
setTimeout(function() {
resolve();
}, 1000);
});
}
let el = document.querySelector('div');
document.querySelector('button').addEventListener('click', e => {
moveTo(el, 100, 100)
.then(function() {
console.log('第一次移動');
return moveTo(el, 200, 200);
})
.then(function() {
console.log('第二次移動');
})
.then(function() {
console.log('第二次移動');
});
});
使用promise的鍊式結構做流程控制,更利于維護、可讀性更強。