談談JavaScript非同步操作Promise
阿新 • • 發佈:2019-01-25
Promise是一個建構函式
var p = new Promise(function(resolve, reject) {
// 非同步操作
setTimeout(function() {
console.log('success');
resolve('async data');
}, 2000);
}).then((data) => {
console.log(data);
});
執行程式碼,會在2秒後輸出“success”和“async data”。注意!我只是new了一個物件,並沒有呼叫它,我們傳進去的函式就已經執行了,這是需要注意的一個細節。所以我們用Promise的時候一般是包在一個函式中,在需要的時候去執行這個函式。
function runAsync() {
var p = new Promise(function(resolve, reject) {
// 非同步操作
setTimeout(function() {
console.log('success');
resolve('async data');
}, 2000);
}).then((data) => {
console.log(data);
});
return p;
}
runAsync();
Promise建構函式之後仍然返回一個Promise物件,呼叫then方法,then()接收一個函式型別的引數,並且會拿到在呼叫resolve方法傳遞的資料。then()其實就跟我們平時說的回撥函式是同一個意思,在非同步操作之後被執行。這就是Promise的作用了,簡單來講,就是能把原來的回撥寫法分離出來,在非同步操作執行完後,用鏈式呼叫的方式執行回撥函式。
Promise的優勢在於,可以在then方法中繼續寫Promise物件並返回,然後繼續呼叫then來進行回撥操作。
function runAsync() {
var p = new Promise(function(resolve, reject) {
// 非同步操作
setTimeout(function() {
console.log('success');
resolve('async data');
}, 2000);
})
return p;
}
runAsync().then((data) => {
console.log('successed result: ' + data);
});
執行這個js檔案,在2秒後輸出”success” 和”successed result: async data”。
在then方法中,你也可以直接return資料而不是Promise物件,在後面的then中就可以接收到資料了。
function runAsync1() {
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('async task 1 success');
resolve('output data1');
}, 2000);
});
return p;
}
function runAsync2() {
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('async task 2 success');
resolve('output data2');
}, 2000);
});
return p;
}
function runAsync3() {
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('async task 3 success');
resolve('output data3');
}, 2000);
});
return p;
}
runAsync1().then(function(data) {
console.log(data);
return runAsync2();
}).then(function(data) {
console.log(data);
return 'return a string not a promise!'
}).then(function(data) {
console.log(data);
});
輸出結果:
async task 1 success
output data1
async task 2 success
output data2
return a string not a promise!
失敗的回撥函式reject和resolve類似,傳遞一個引數,當執行失敗時將對應的資料傳遞過去。
Promise.all
function resolve(millis, value) {
return new Promise(resolve => setTimeout(() => resolve(value), millis));
}
Promise.all([
resolve(5000, 1),
resolve(6000, 2),
{ hello: 3}
]).then(values => console.log(values));
// [1, 2, { hello: 3 }]