Promise简介
相当于一个容器,允许你为异步操作的成功和失败分别绑定相应的处理方法,保存着未来才会结束的事件(异步操作)的一个结果
各种异步操作都可以用同样的方法进行处理
对象的状态不受外界影响,处理异步操作有三个状态:
- pending(进行)
- fulfilled(成功)
- rejected(失败)
一旦状态改变,就不会再变化,任何时候都可以得到这个结果
基本使用
function timeout(ms) {
// Promise 对象
return new Promise((resolved, rejected) => {
let res = {
code: 200,
data: {
msg: 'Hello Promise resolved'
}
}
setTimeout(() => {
if (res.code === 200) {
resolved(res.data)
} else {
rejected("Promise reject")
}
}, ms)
})
}
// res 接收成功回调的结果, err 结束失败回调的结果
timeout(2000).then(res => {
console.log(res)
}, err => {
console.log(err)
})
then
第一个参数是resolve回调函数,第二个参数可选,为reject状态的回调函数
then()方法返回一个新的promise实例,所以可以采用链式编程的写法
timeout(1000).then(res => {
console.log(res); // { msg: 'Hello Promise resolved' }
return res.msg;
}).then(res => {
console.log(res); // Hello Promise resolved
})
catch
接收reject状态的回调函数
timeout(1000).then(res => {
console.log(res)
}).catch(err => {
console.log(err);
})
// --------------- 等价于 ----------------
timeout(1000).then(res => {
console.log(res)
}).then(null, err => {
console.log(err);
})
Promise封装ajax
const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const getJSON = function (url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.onreadystatechange = handler;
xhr.setRequestHeader('ACCEPT', 'appliction/json');
// 发送
xhr.send();
function handler() {
console.log(this);
if (this.readyState === 4) {
if (this.status === 200) {
resolve(this.location);
} else {
reject(new Error(this.statusText));
}
}
}
})
}
getJSON("https://geoapi.heweather.net/v2/city/lookup?location=beij&key=xxx").then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
Promise方法
resole
能将现有的任何对象转换成一个Promise
对象
let p = Promise.resolve('foo');
// 等价于 ==>
let p1 = new Promise(resolve => resolve('foo'));
p.then(data => {
console.log(data); // foo
})
reject
返回一个带有拒绝原因的Promise
对象。
let p = Promise.reject(new Error('fail'));
p.then(res => {
}).catch(err=> {
console.log(err); // Error: fail
})
all
返回一个 Promise
实例,此实例在 iterable
参数内所有的 promise
都完成(resolved)或参数中不包含 promise
时回调完成(resolve);如果参数中 promise
有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败 promise
的结果。
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
allSelected
返回一个在所有给定的promise都已经fulfilled
或rejected
后的promise,并带有一个对象数组,每个对象表示对应的promise结果。
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];
Promise.allSettled(promises).then(results => results.forEach(result => console.log(result.status)));
// expected output:
// "fulfilled"
// "rejected"
race
返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
const timeout = function (ms) {
return new Promise((resolved, rejected) => {
setTimeout(() => {
rejected(new Error('请求超时!'))
}, ms)
})
}
const requestFile = function() {
return new Promise((resolved, rejected) => {
// 请求文件
})
}
// 如果3秒内requestFile没有相应,将返回请求超时
let p = new Promise.race([requestFile(),timeout(3000)]);
p.then(res=> {
// ...
})
finally
返回一个Promise
,在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise
是否成功完成后都需要执行的代码提供了一种方式。
timeout(1000).then(res => {
console.log(res)
}).catch(err => {
console.log(err);
}).finally(() => {
console.log('finally')
})
async
async返回一个Promise对象
async是Generator的一个语法糖
使异步操作更加方便
await
操作符用于等待一个Promise
对象,返回 Promise 对象的处理结果。它只能在异步函数 async function
中使用。如果等待值不是promise对象,await
会把等待值转换为已正常处理的Promise,然后等待其处理结果。
async function fun() {
return await 'hello async';
}
fun().then(v => {console.log(v)}).catch(e=>console.log(e));
如果async函数中有多个await,then会等待所有的await指令运行完的结果,才去执行
async function fun() {
let s = await 'hello async';
let data = await s.split('');
return data;
}
fun().then(v => {console.log(v)}).catch(e=>console.log(e));
如果一个await 的结果为reject,则立即返回reject的结果,不会执行后去的await
async function f() {
await Promise.reject('出错');
return await Promise.resolve('完成');
}
f().then(v => {console.log(v)}).catch(e=>console.log(e)); // 出错
使用try...catch
使得某个await结果为reject时继续执行
async function f() {
try {
await Promise.reject('出错');
} catch (err) {
console.log(err); // 出错
}
return await Promise.resolve('完成');
}
f().then(v => {console.log(v)}).catch(e=>console.log(e)); // 完成
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!