JavaScript 中使用 Promise

异步编程的几种模式

回调和事件
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 = new Date().getTime();
let log = (msg) => console.log(msg + " - " + (new Date().getTime() - start))

log("mark 1");
let p = new Promise((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 = new Promise((res, rej)=> {
		console.log("mark 2");
		let out = ()=>{
			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 的行为:

class MyPromise{
    constructor(callback){
        let res = (params)=> this.res(params); // 这里使用了类似拦截器或者代理的效果,对目标 res 进行包裹
        let rej = (params)=> this.rej(params);
        this.status = 0; // pending
        this.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; // fullfiled
        this.actions.forEach(action=> action[0](params));
    }

    rej(params){
        this.params = params;
        this.status = 2; // rejected
        this.actions.forEach(action=> action[1](params));
    }
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值