现像
Promise 同步与异步的位置
// Promise() 同步
// executor 同步
const p = new Promise((resolve, reject) => {
})
// 异步
p.then((res) => {
})
问题:
为什么 Promise 执行是同步,p.then 是异步?
回答这个问题,先看一个例子:
// 已引入jQuery
$.ajax({
url: 'http://localhost:3000/data.json', // [{"name":"zhangsan"}, {"name":"lisi"}, {"name": "wangwu"}]
success (data){
console.log(getName(data));
}
})
console.log('I am a crazy guy.');
function getName(data){
return data.map(item => item.name);
}
输入的结果是会先打印 'I am a crazy guy.'
,再打印 ajax 中 sucess 的 console.log 数组的结果。
原因是 ajax 是异步的操作,会存在执行的时间。
如果我们想把 ajax 的回调变成同步的话,把ajax的 async
改为 false,
var data = $.ajax({
url: 'http://localhost:3000/data.json', // [{"name":"zhangsan"}, {"name":"lisi"}, {"name": "wangwu"}]
async: false
})
console.log(getName(data.responseJSON);
console.log('I am a crazy guy.');
function getName(data){
return data.map(item => item.name);
}
这时就会先打印 ajax 的 data(阻塞),再打印出 crazy guy,变为同步的关系。
虽然变成了同步关系,但是没有完成逻辑分离的动作。因为ajax下面每一个语句都是同步的关系,crazy guy 也被 ajax 阻塞了。
这样不符合我们的需求,才有了 Promise 的出现。
const p = new Promise((resolve, reject) => {
$.ajax({
url: 'http://localhost:3000/data.json',
success(data) {
resolve(data);
}
});
});
p.then((res => {
console.log(getName(res));
}));
console.log('I am a crazy guy.');
function getName(data) {
return data.map(item => item.name);
}
会先打印 crazy guy,再打印 ajax 输出。完美解决 ajax 的 async 为 false,导致后面语句全部阻塞的问题。
回调地狱的最优解
Promise 配合上 async / await
function getData() {
return new Promise((resolve, reject) => {
$.ajax({
url: 'http://localhost:3000/data.json',
success(data) {
resolve(data);
}
});
})
}
doSth();
async function doSth() {
const data = await getData();
console.log(getNames(data));
}
console.log('I am a crazy guy.');
function getName(data) {
return data.map(item => item.name);
}
总结
Promise 存在意义
Promise 是异步问题同步化解决处理的最优化方案。可以避免异步程序同步化阻塞同步代码执行。
Promise 只是顺路把回调地狱的问题改为链式操作,但也不是其存在的目的和最优的解决回调地狱的方案。