Promise

定义

异步编程的解决方案。

特点

  1. 对象状态不受外界影响
  2. 一旦状态改变就不会再变,任何时候获取的都是改变后的结果。

三种状态

- pending: 进行中
- fulfilled/resolved:已成功
- rejected: 已失败

状态改变

1、 pending转为fulfilled
2、pending转为rejected

有且仅有以上俩种状态转变,且不可逆转

基本用法

let p = new Promise((resolve, reject) => {});
console.log(p);

在这里插入图片描述

  • Promise构造函数接收俩个参数(函数)
  1. resolve: 将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去
  2. reject::将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
  • 在p实例中除prototype外还有俩个属性: promiseState、 PromiseResult.

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

let p = new Promise((resolve,reject)=>{
  resolve('resolve函数将Promise状态从pending变成resolved')
})
p.then((res)=>{
  console.log(res,'Promise对象的状态变为resolved时调用');
},(err)=>{
  console.log(err, 'Promise对象的状态变为rejected时调用');
})

在这里插入图片描述

let p = new Promise((resolve,reject)=>{
  reject('resolve函数将Promise状态从pending变成rejected')
})
p.then((res)=>{
  console.log(res,'Promise对象的状态变为resolved时调用');
},(err)=>{
  console.log(err, 'Promise对象的状态变为rejected时调用');
})

在这里插入图片描述
Promsie一旦被建就会立即执行

let p = new Promise((resolve,reject)=>{
  console.log('Promise');
  resolve()
})
p.then(res=>{
  console.log('resolved');
})
console.log(123);

在这里插入图片描述
resolve函数除了正常的参数外,还可以是Promise实例

let p1 = new Promise((resolve,reject)=>{
  resolve('123')
})
let p2 = new Promise((resolve,reject)=>{
  resolve(p1)
})
p2.then(res=>{
  console.log(res);
})

如果resolve的参数为Promsie实例时,前一个Promise的状态为pending,则后一个promise的回调函数需等前一个promise状态改变后执行;如果前一个状态为fulfilled或rejected,则后一个promise的回调函数回立即执行

const p1 = new Promise((resolve, reject) => {});
const p2 = new Promise((resolve, reject) => {
  resolve(p1);
});
p2.then((res) => {
  console.log(res);
}).catch((err) => {
  console.log(err);
});
// p1的状态始终为pending,p2的回调函数不执行
const p1 = new Promise((resolve, reject) => {
  resolve('p1状态改为fulfilled')
});
const p2 = new Promise((resolve, reject) => {
  resolve(p1);
});
p2.then((res) => {
  console.log(res); // p1状态改为fulfilled
}).catch((err) => {
  console.log(err);
});
// p1的状态由pending转为fulfilled后,p2回调函数执行,并将p1作为参数传递
const p1 = new Promise((resolve, reject) => {
  setTimeout(()=>{
    reject(new Error('p1的状态改为rejected'))
  },1000)
});
const p2 = new Promise((resolve, reject) => {
  resolve(p1);
});
p2.then((res) => {
  console.log(res); 
}).catch((err) => {
  console.log(err); // Error: p1的状态改为rejected
});
// p1的状态由pending转为rejected后,p2回调函数执行,并将p1作为参数传递

通过Promise实现ajax请求

let p = new Promise((resolve, reject) => {
  let xhr = new XMLHttpRequest();
  xhr.open("GET", "url");
  xhr.send();
  xhr.responseType ='json'
  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        resolve(xhr.response)
      } else {
        reject(xhr.status);
      }
    }
  };
});
p.then(
  (res) => {
    console.log(res, "res");
  },
  (err) => {
    console.log(err, "err");
  }
);

实例方法

  1. Promise.prototype.then()
  • 用于为Promise添加状态改变时的回调函数
  • 俩个参数(函数):状态为fulfilled时的回调, 状态为rejected的回调
  • 返回的是一个新的Promise对象,因此可以使用链式调用
const p = new Promise((resolve, reject
  resolve("data");
});
p.then((res) => {
  console.log(res, "then1");
  return res;
})
  .then((res) => {
    console.log(res, "then2");
  })
  .then((res) => {
    console.log(res, "then3");
  });

在这里插入图片描述
以上代码创建了Promise实例p,通过第一个then方法调用,输出data,第一个then方法又是一个新的Promise实例,并将上述状态返回,于是通过第二个then方法调用可输出data,而第二个then方法无任何返回值,所以第三个then方法调用时接收不到任何值,所以返回undefined
2. Promise.prototype.catch()

  • 用于指定发生错误的回调函数
const p = new Promise((resolve, r
  reject(new Error("err"));
});
p.then((res) => {}).catch((err) =
  console.log(err);  // Error: er
});
// 如果p的状态为fulfilled,则执行then方法,如果then方法中跑出异常也会执行catch
const p = new Promise((resolve, reject) => {
  resolve('resolved')
});
p.then((res) => {
  throw '抛出异常'
}).catch((err) => {
  console.log(err);  // Error: err
});

建议: then方法的第二个参数使用调用catch方法代替,因为catch方法还是一个Promise对象,除可以处理promise内部的错误外还可以继续调用后面的then方法

const p = new Promise((resolve, reject) => {
  reject(new Error("出错了"));
});
p.catch((err) => {
  console.log(err, "err");
}).then((res) => {
  console.log(res, 'then函数在catch执行后也被执行了');
});

在这里插入图片描述

const p = new Promise((resolve, reject) => {
  resolve(x + 2);
});
p.catch((err) => {
  console.log(err, "err");
}).then((res) => {
  console.log(res, "then函数在catch执行后也被
});

在这里插入图片描述

  • 如果状态为fulfilled则可跳过catch方法
const p = new Promise((resolve, reject) 
  let x = 3
  resolve(x + 2);
});
p.catch((err) => {
  console.log(err, "err");
}).then((res) => {
  console.log(res, "then函数执行了");
});

在这里插入图片描述

  • catch自身的错误只能被下一个catch捕获
const p = new Promise((resolve, reject) =
  resolve(x + 2);
});
p.catch((err) => {
  console.log(err, "promise实例出错");
  y + 1;
}).catch((err) => {
  console.log(err, "上一个catch出错");
});

在这里插入图片描述
3. Promise.prototype.finally()

  • 无论Promise最后的状态如何都会执行的操作

Promise常用方法

  1. Promise.all()
  • 用于将多个Promsie实例,包装成一个新的Promise 实例
  • 新的Promise实例的状态由其中每一个Promise来决定
    1) 如果每一个Promise的状态都为fulfilled,新的Promise实例的状态为fulfilled,每一个Promise的返回值形成一个数组,传递给新的Promise实例的回调函数
const sendAjax = (url) => {
  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.send();
    xhr.responseType = "json";
    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          resolve(xhr.response);
        } else {
          reject(xhr.status);
        }
      }
    };
  });
};
const p1 = sendAjax("url"); // 此url应为可访问的接口地址
const p2 = sendAjax("url"); // 此url应为可访问的接口地址
Promise.all([p1, p2])
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.log(err, "err");
  });

在这里插入图片描述
2) 如果其中有一个Promise的状态为rejected,则新的Promise实例的状态为rejected,第一个被rejected的返回值,传递给新的Promise实例的回调函数

const p3 = sendAjax("url"); // 此url应为可访问的接口地址
const p4= new Promise((resolve, reject) => {
  reject(new Error("p4的Promise状态为rejected"));
});
const p5 = new Promise((resolve, reject) => {
  reject(new Error("p5的状态为rejected"));
});
Promise.all([p3, p4, p5])
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.log(err, "err");
  });

在这里插入图片描述
每个 promise状态均为fulfilled时,且有自己then方法时

const p1 = new Promise((resolve, reject) => {
  resolve("p1");
})
  .then((res) => {
    console.log(res, "res1");
    return res
  })
  .catch((err) => {
    console.log(err, "err1");
  });
const p2 = new Promise((resolve, reject) => {
  resolve("p2");
})
  .then((res) => {
    console.log(res, "res2");
  })
  .catch((err) => {
    console.log(err, "err2");
  });
const p3 = new Promise((resolve, reject) => {
  resolve("p3");
})
  .then((res) => {
    console.log(res, "res3");
  })
  .catch((err) => {
    console.log(err, "err3");
  });
Promise.all([p1,p2,p3]).then(res=>{
  console.log(res,'resNew');
}).catch(err=>{
  console.log(err,'errNew');
})

在这里插入图片描述
实例状态中含有rejected,且每个rejected状态的实例有自己的catch方法时,不会调用新实例的catch方法

const p1 = new Promise((resolve, reject) =
  resolve("p1");
})
  .then((res) => {
    console.log(res, "res1");
    return res
  })
  .catch((err) => {
    console.log(err, "err1");
  });
const p2 = new Promise((resolve, reject) =
  reject("p2");
})
  .then((res) => {
    console.log(res, "res2");
  })
  .catch((err) => {
    console.log(err, "err2");
  });
const p3 = new Promise((resolve, reject) =
  resolve("p3");
})
  .then((res) => {
    console.log(res, "res3");
  })
  .catch((err) => {
    console.log(err, "err3");
  });
Promise.all([p1,p2,p3]).then(res=>{
  console.log(res,'resNew');
}).catch(err=>{
  console.log(err,'errNew');
})
  1. Promise.race()
  • 将多个 Promise 实例,包装成一个新的 Promise 实例
  • 每个Promise实例,有一个先改变状态新的Promise实例就会改变状态,且将最先改变状态的实例的的返回值,传递给新Promise实例的回调函数
const p1 = new Promise((resolve, 
  setTimeout(() => {
    resolve("p1");
  },3000);
});
const p2 = new Promise((resolve, 
  setTimeout(() => {
    resolve("p2");
  }, 2000);
});
const p3 = new Promise((resolve, 
  setTimeout(() => {
    resolve("p3");
  }, 1000);
});
Promise.race([p1, p2, p3])
  .then((res) => {
    console.log(res, "newRes");
  })
  .catch((err) => {
    console.log(err, "newErr");
  });

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值