为什么使用Promise?
解决 更好的解决回调问题,减少嵌套
Promise 必须为以下三种状态之一:
等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected)。
一旦Promise 被 resolve 或 reject,不能再迁移至其他任何状态(即状态 immutable)。
基本过程:
1. 初始化 Promise 状态(pending)
2. 立即执行 Promise 中传入的 fn 函数,将Promise 内部 resolve、reject 函数作为参数传递给 fn ,按事件机制时机处理
3. 执行 then(..) 注册回调处理数组(then 方法可被同一个 promise 调用多次)
4. Promise里的关键是要保证,then方法传入的参数 onFulfilled 和 onRejected,必须在then方法被调用的那一轮事件循环之后的新执行栈中执行。
new Promise(
function (resolve, reject) {
resolve('成功')
reject('失败')
}
);
缺点
promise一旦创建,无法取消
.then方法每次调用都会创建一个新的promise对象,一定程度上造成了内存的浪费
Promise.all([async1(), async2(), async3()]).then(function (results) {
console.log(results);
});
Promise.race([requestImg(), timeout()]).then(function (results) {
console.log(results);
}).catch(function (reason) {
console.log(reason);
});
Promise.all() 和 romise.race() 都具有短路特性
调试
Promise 有两个问题:
不能在返回表达式的箭头函数中设置断点;
在 then 代码块中设置断点,调试器不会跳到下一个 then,因为它只会跳过异步代码;
.then(r => {
return serverStatusPromise(r);
})
.then(resp => {
console.log(resp.statusCode);
})
var statusProm = fetchServerStatus();
var promA = statusProm.then(r => (r.statusCode === 200 ? "good" : "bad"));
var promB = promA.then(r => (r === "good" ? "ALL OK" : "NOTOK"));
var promC = statusProm.then(r => fetchThisAnotherThing());
return new Promise((res, rej) => {
fs.readFile("/etc/passwd", function(err, data) {
if (err) return rej(err);
return res(data);
});
});
return fs.readFile("/etc/passwd", function(err, data) {
if (err) return err;
return data;
});
var similarProm = new Promise(res => res(5));
var prom = Promise.resolve(5);
function goodProm(maybePromise) {
return Promise.resolve(maybePromise);
}
goodProm(5).then(console.log);
var sixPromise = fetchMeNumber(6);
goodProm(sixPromise).then(console.log);
goodProm(Promise.resolve(Promise.resolve(5))).then(console.log);
var rejProm = new Promise((res, reject) => reject(5));
rejProm.catch(e => console.log(e))
function foo(myVal) {
if (!mVal) {
return Promise.reject(new Error('myVal is required'))
}
return new Promise((res, rej) => {
})
}
.then(() => 5.length)
.catch(e => {
return 5;
})
.then(r => {
console.log(r);
})
.catch(e => {
console.error(e);
})
.then(() => 5.length)
.catch(e => {
errorLogger(e);
return Promise.reject(e);
})
.then(r => {
console.log(r);
})
.catch(e => {
console.error(e);
})
.then(function() {
return Promise.reject(new Error('something wrong happened'));
}).catch(function(e) {
console.error(e);
});
.then(function() {
return Promise.reject(new Error('something wrong happened'));
}, function(e) {
console.error(e);
});
let promise = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'promise');
});
promise.then((value) => {
console.log(value);
throw '抛出一个异常'
}).catch((e) => {
console.log(e)
})
使用Async/Await
.then(myVal => {
const promA = foo(myVal);
const promB = anotherPromMake(myVal);
return Promise.all([prom, anotherProm])
})
.then(([valA, valB]) => {
console.log(valA, valB)
return hungryFunc(valA, valB)
})