在JavaScript的世界中,所有代碼都是單線程執行的。
由於這個“缺陷”,導致JavaScript的所有網絡操作,瀏覽器事件,都必須是異步執行。異步執行可以用回調函數實現:
function callback() {
console.log('Done');
}
console.log('before setTimeout()');
setTimeout(callback, 1000); // 1秒鐘後調用callback函數
console.log('after setTimeout()');
可看見執行順序爲before setTimeout() 和 after setTimeout() 和 done 是異步執行的。
我們可以用promise來修改這一函數 promise有兩個方法resolve和reject,將異步調用理得更加明朗,易於理解。
resolve接收成功後的值,reject用於接收失敗後的值,隨後new 一個 promise後,then代表成功後執行的方法,catch代表失敗後執行的方法。
function test(resolve, reject) {
var timeOut = Math.random() * 2;
log('set timeout to: ' + timeOut + ' seconds.');
setTimeout(function () {
if (timeOut < 1) {
log('call resolve()...');
resolve('200 OK');
}
else {
log('call reject()...');
reject('timeout in ' + timeOut + ' seconds.');
}
}, timeOut * 1000);
}
生成一個promise對象。
var p1 = new Promise(test);
var p2 = p1.then(function (result) {
console.log('成功:' + result);
});
var p3 = p2.catch(function (reason) {
console.log('失敗:' + reason);
});
可見promise的最大好處便是在異步執行的流程中,把執行代碼和處理結果的代碼分離./
比如有若干個任務,先做任務1,再做任務2,成功後再做任務3
用鏈串的方法。
function multiply(input) {
return new Promise(function (resolve, reject) {
console.log('calculating ' + input + ' x ' + input + '...');
setTimeout(resolve, 500, input * input);
});
}
// 0.5秒後返回input+input的計算結果:
function add(input) {
return new Promise(function (resolve, reject) {
console.log('calculating ' + input + ' + ' + input + '...');
setTimeout(resolve, 500, input + input);
});
}
var p = new Promise(function (resolve, reject) {
console.log('start new Promise...');
resolve(123);
});
p.then(multiply)
.then(add)
.then(function (result) {
console.log('Got value: ' + result);
});
查看輸出