javascript 学习笔记
Promise
介绍
ES6中一个非常重要和好用的特性就是Promise,Promise是异步编程的一种解决方案。
一种很常见的场景应该就是网络请求了。我们封装一个网络请求的函数,因为不能立即拿到结果,所以不能像简单的3+4=7一样将结果返回。所以往往会传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去。如果只是一个简单的网络请求,那么这种方案不会给我们带来很大的麻烦。但是,当网络请求非常复杂时,就会出现“回调地狱”。
promise使用
- new Promise创建一个Promise对象;
- 小括号中((resolve, reject) => {})是一个函数,在创建Promise时,传入的这个函数是固定的(一般都会这样写)
- resolve和reject它们两个也是函数,通常情况下,会根据请求数据的成功和失败来决定调用哪一个。
- 如果是成功的,那么通常调用resolve(messsage),这个时候,后续的then会被回调。
- 如果是失败的,那么通常会调用reject(error),这个时候,后续的catch会被回调。
new Promise(((resolve, reject) => {
setTimeout(function () {
let data = "data1";
console.log("get "+ data);
// 异步请求成功时,调用resolve,会走到then
// resolve(data);
// 异步请求失败时,调用reject,会走到catch
reject("get " + data + " failed");
}, 3000)
})).then(data => {
console.log("deal with " + data);
}).catch(error => {
console.log(error);
})
Promise的三种状态
- 首先, 当我们开发中有异步操作时, 就可以给异步操作包装一个Promise。
- Promise异步操作之后会有三种状态:
pending:等待状态,比如正在进行网络请求,或者定时器没有到时间。
fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then()。
reject:拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch()。
Promise链式调用
- 返回promise对象:
new Promise(((resolve, reject) => {
setTimeout(function () {
let data = "data1";
console.log("get "+ data);
resolve(data);
}, 3000)
})).then(data => {
console.log("deal with " + data);
// 第二次异步请求,返回一个promise对象
return new Promise( (resolve, reject) => {
setTimeout(() => {
let data = "data2";
console.log("get "+ data);
// 异步请求成功时,调用resolve,会走到then
resolve(data);
// 异步请求失败时,调用reject,会走到catch
//reject("get "+ data + " failed.")
}, 3000)
})
}).then(data => {
console.log("deal with "+ data);
}).catch(error => {
console.log(error);
})
- 特殊场景:
如果只有第一次有异步请求,后面几步都没有异步请求,只是为了区分第一次数据和后面数据的处理逻辑:
return时不需要new Promise对象,直接使用Promise.resolve即可
new Promise(((resolve) => {
setTimeout(function () {
let data = "aaaa";
console.log("get "+ data);
resolve(data);
}, 3000)
})).then(data => {
console.log("处理请求1结果");
return Promise.resolve(data + "bbbb")
}).then(data => {
console.log("deal with "+ data);
return Promise.resolve(data + "cccc")
}).then(data => {
console.log("deal with "+ data);
}).catch(error => {
console.log(error);
})
进一步简写,return是不需要再写Promise.resolve
new Promise(((resolve) => {
setTimeout(function () {
let data = "aaaa";
console.log("get "+ data);
resolve(data);
}, 3000)
})).then(data => {
console.log("处理请求1结果");
return data + "bbbb"
}).then(data => {
console.log("deal with "+ data);
return data + "cccc"
}).then(data => {
console.log("deal with "+ data);
}).catch(error => {
console.log(error);
})
Promise.all
如果结果处理同时依赖多个请求结果,可以使用Promise.all(),括号中传入多个promise对象,等到多个请求都返回结果是,会走到then再统一处理。
其中有一个请求失败时,最终都会走到catch。
let request1 = new Promise(((resolve) => {
setTimeout(function () {
console.log("get request1");
resolve("request1");
}, 3000)
}));
let request2 = new Promise(((resolve, reject) => {
setTimeout(function () {
console.log("get request2");
resolve("request2");
// reject("request2");
}, 5000)
}));
Promise.all([
request1, request2
]).then(data => {
console.log(data);
}).catch(err => {
console.log("get failed:" + err);
})