美文网首页JavaScript 进阶营
10分钟手写一个Promise

10分钟手写一个Promise

作者: Kagashino | 来源:发表于2018-08-15 18:05 被阅读0次

不要被then需要异步执行吓到了,then传入的是个函数,什么时候调用,应该由第一次回调决定
静态的all、race等方法,后面再补充

function promise(func){
    this.state = 'pending'; //状态
    this.resolveArg; //回调参数,下同
    this.rejectArg;
    this.thenQueue = []; //调用队列
    this.thenable = true;

    this.resolveFunc = _resolveFunc.bind(this);
    this.rejectFunc  = _rejectFunc.bind(this);
    this.catchFunc   = _catchFunc.bind(this);
    //将 res,rej回调传入作用域内并执行主函数
    try {
        func(this.resolveFunc,this.rejectFunc)
    } catch (e) {
        this.catchFunc(e);
    }
}
promise.prototype = {
    constructor : promise,//绑定构造器
    /* 调用then,只需要把传入的回调压进then队列里即可,不需要timeout操作*/
    then : function(res,rej) {
        if (!this.thenable) {
            return this;
        }
        //
        this.thenQueue.push({
            res : res,
            rej : rej
        })
        return this;
    },
    catch: function(func) {
        this.catchFunc = func;
        return this
    },
    finally: function (func) {
        this.finallyFunc = func;
        this.thenable = false;
        return this;
    }
}
/* rej、res回调会将then队列里的函数依次执行,并且上一个then的返回值作为下一个then的参数 */
function _rejectFunc (args) {
    this.rejectArg = args;
    this.state     = 'rejected'
    if(!this.thenQueue.length){return;}
    while (this.thenQueue.length) {
        rejCallback = this.thenQueue.shift().rej;
        try {
            var newReturns = rejCallback(this.rejectArg);
            this.rejectArg = newReturns;
        } catch (e) {
            this.catchFunc(e)
        }
    }
    this.finallyFunc && this.finallyFunc();
    this.thenable = false;
}

function _resolveFunc (args) {
    this.resolveArg = args;
    this.state      = 'fullfilled'
    if(!this.thenQueue.length){return;}
    while (this.thenQueue.length) {
        resCallback = this.thenQueue.shift().res;
        try {
            var newReturns  = resCallback(this.resolveArg)
            this.resolveArg = newReturns;
        } catch(e) {
            this.catchFunc(e)
        }
    }
    this.finallyFunc && this.finallyFunc();
    this.thenable = false;
}
function _catchFunc (e){
    throw Error('Uncaught promise error:' + e)
}
new promise(res=>{
    setTimeout(()=>{
        res([123])
    },1000)
}).then(res=>{
    console.log('res',res)
    return 'bbb'
}).then(res=>{
    console.log(res)
})

存在的问题

Promise.then是在下一个MicroTask调用的,而上述的代码是同步执行

new promise(res=>{
  setTimeout(()=>{
    res()
  })
  console.log('抢先一步')
}).then()

设置了setTimeout会使then在MacroTask之后调用
Node.js中可以使用setImmediate,就能使其真正的在下一个MicroTask执行

相关文章

  • 手写Promise

    手写 Promise 我们会通过手写一个符合 Promise/A+ 规范的 Promise 来深入理解它,并且手写...

  • 手写promise

    手写promise 带大家手写一个 promis。在手写之前我会先简单介绍一下为什么要使用promise、prom...

  • es5 手写promise

    参考自 前端精髓--手写一个Promise

  • 手写 Promise 系列 --- 3

    在前两篇(手写 Promise 系列 --- 1)和(手写 Promise 系列 ---2) 中,达成了3个目标 ...

  • 手写Promise

    $ 正常的promise用法   $ 手写的Promise   # 测试可行性

  • 纯手写实现自己的nodejs promise 库

    纯手写实现自己的nodejs promise 库什么是Promise?promise 链Async/Await后续...

  • 手写基础 promise

    1. 前言 玩下吧 手写 promise,看看能写成啥样 2. promise 基础结构 3. 手写`promi...

  • 手写promise

    promise 手写 代码来源:darrell-wheels promise 30分钟,带你实现一个符合规范的 P...

  • JS常见手写代码题(二)

    1、用闭包手写一个cache工具 2、手写一个简易的JQuery,考虑插件和扩展性 3、手写Promise加载一张...

  • 手写简易Promise

    promise的用法 手写promise需要注意的地方1)接受一个函数(后文称为executor函数)作为参数,e...

网友评论

    本文标题:10分钟手写一个Promise

    本文链接:https://www.haomeiwen.com/subject/ikowbftx.html