JavaScript 中使用 Promise

2022-07-31 08:39:57

异步编程的几种模式

回调和事件
Promise
Async,Wait

Promise

Promise 是 ES6 提供的原生类,简单的说就是一个容器,里面保存着某个异步执行的操作结果(也就是说未来才会获得的结果)。类似于Java 中的 Future 类。

三种状态:pending(进行中),fulfilled(成功, resolved),rejected(失败)
状态变化:

  1. pending => fulfilled
  2. pending => rejected

有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

缺点:

  1. 无法取消,一旦新建就会立即执行;
  2. 如果不设置回调函数,Promise 内部会抛出错误;
  3. 当出于 pending 状态时,无法得知目前进展到哪一个阶段;

示例 1:

let start=newDate().getTime();letlog=(msg)=> console.log(msg+" - "+(newDate().getTime()- start))log("mark 1");let p=newPromise((res, rej)=>{log("mark 2");res("mark 5");log("mark 3");})
	
p.then((value)=>log(value));
p.then((value)=>log(value));log("mark 4");

示例 2


console.log("mark 1");let p=newPromise((res, rej)=>{
		console.log("mark 2");letout=()=>{
			console.log("xxxx");res("vava");}setTimeout(()=>{res("mark 5")},2000,);
		console.log("mark 3");})
	
p.then((value)=>console.log(value));
p.then((value)=>console.log(value));
console.log("mark 4");

说明:

  1. 从外部看来,Promise 的创建不会导致程序阻塞;
  2. 调用 then 方法,出入的回调函数会被延迟执行;
  3. then 方法可以重复调用;
  4. then(success, fail):then 方法可以接受两个回调函数作为参数,第一个回调函数在 Promise 对象的状态变为 resolved 时调用,第二个回调函数在 Promise 对象的状态转变为 rejected 时调用。

MyPromise

可以通过下面的自定义类,来模拟 Promise 的行为:

classMyPromise{constructor(callback){letres=(params)=>this.res(params);// 这里使用了类似拦截器或者代理的效果,对目标 res 进行包裹letrej=(params)=>this.rej(params);this.status=0;// pendingthis.actions=[];this.params=null;callback(res, rej);// 当创建 MyPromise 对象时,立即调用传入的回调方法;}// 实际的 res,rej 函数实例是通过 then 函数传进来的then(res, rej){if(this.status===0){// 如果处在 pending 状态,就将 res,rej 回调方法缓存起来,等有结果了再调this.actions.push([res, rej]);return;}if(this.status===1){res(this.params);return;}if(this.status===2){rej(this.params);}}res(params){this.params= params;this.status=1;// fullfiledthis.actions.forEach(action=> action[0](params));}rej(params){this.params= params;this.status=2;// rejectedthis.actions.forEach(action=> action[1](params));}}
  • 作者:墨城之左
  • 原文链接:https://gnetna.blog.csdn.net/article/details/105414916
    更新时间:2022-07-31 08:39:57