资讯专栏INFORMATION COLUMN

js手动实现promise

VPointer / 784人阅读

摘要:依次循环直到当前没有子如何让异步的在函数中拿到将函数和放入同一个对象对象里面的时候将设置。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对对象添加回调函数,也会立即得到这个结果。

let promise = new Promise((resolve111, reject) => {
    //这里放入我们要执行的函数,可能是同步,也可能是异步, 这里我们就来写一个异步的执行
    setTimeout(() => {
        resolve111("hello");
    }, 100)
})
    
promise.then(data => {
    console.log(data);
    return new Promise(function(res, rej) {
        setTimeout(function() {
            console.log(2);
            res();
        }, 100)
    })
}, err => {console.log(err)})

promise的执行流程如如下:

var i = 1
function Promise(fn) {
    this.id = i++;
    this.status = "PENDING";
    this.value = null;
    this.deffered = [];
    fn.call(this, this.resolve.bind(this), this.reject.bind(this))
}

Promise.prototype = {
    constructor: Promise,
    then: function(onfulfilled, onrejected) {
        var obj = {
            onfulfilled: onfulfilled,
            onrejected: onrejected
        }
        obj.promise = new this.constructor(function() {});
        console.log(this.status)
        if (this.status === "PENDING") {
            this.deffered.push(obj);
        }
        console.log(this.deffered)
        return obj.promise;
    },
    resolve: function(data) {
        this.status = "FULFILLED";
        this.value = data;
        this.deffered.forEach(item => {
            let p = item.onfulfilled(this.value);
            if (p && p.constructor === Promise) {
                p.deffered = item.promise.deffered;
            }
        });
    },
    reject: function(err) {
        this.status = "REJECTED";
        this.value = err;
        this.deffered.forEach(item => {
            let p = item.onrejected(this.value);
            if (p && p.constructor === Promise) {
                p.deffered = item.promise.deffered;
            }
        });
    }
}

then方法需要返回一个新的子Promise, 并且前后的Promise需要建立联系,才能决定他们的执行顺序。这里用id标识每个promise。

Promise链式操作中,执行顺序是如何保证的

每个promise后面链一个对象该对象包含onfulfiled,onrejected,子promise三个属性,当父promise 状态改变完毕,执行完相应的onfulfiled/onfulfiled的时候呢,拿到子promise,在等待这个子promise状态改变,再执行相应的onfulfiled/onfulfiled。依次循环直到当前promise没有子promise


如何让异步的value在thenable函数中拿到

将resolve/reject函数和onfulfiled/onrejected放入同一个对象(promise对象)里面,resolve/reject的时候将value设置this.value=xxx。onfulfiled/onrejected执行的时候呢,onfulfiled(this.value)即可。

在这里避免头晕,解释一下,onfulfilled和onrejected指的是then里面的两个函数。

状态机制切换

 如图所示,状态只能由pengding-->fulfilled,或者由pending-->rejected这样转变。

 只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100869.html

相关文章

  • js来聊聊异步编程

    摘要:实例生成以后,可以用方法分别指定状态和状态的回调函数处理返回的结果。 文章的目的 揭开go的 gorouter,c#的 async/await等 使用同步的写法写异步代码的神秘面纱 , 证明其本质就是一个语法糖 为什么使用js来讲异步编程 因为js可以通过编程语言自己的语法特性,实现async/await语法 js异步最底层写法promise const promise = new P...

    huashiou 评论0 收藏0
  • 异步发展流程 —— Generators + co 让异步更优雅

    摘要:遍历器原有的表示集合的数据结构,主要有和,在中又加入了和,这样就有了四种数据集合,还可以组合使用它们,如数组的成员是或,这样就需要一种统一的接口机制,用来处理所有不同的数据结构。 showImg(https://segmentfault.com/img/remote/1460000018998438?w=900&h=431); 阅读原文 Generators 简介 Generato...

    dingda 评论0 收藏0
  • node.js与ThreadLocal

    摘要:变量的说法来自于,这是在多线程模型下出现并发问题的一种解决方案。目前已经有库实现了应用层栈帧的可控编码,同时可以在该栈帧存活阶段绑定相关数据,我们便可以利用这种特性实现类似多线程下的变量。 ThreadLocal变量的说法来自于Java,这是在多线程模型下出现并发问题的一种解决方案。ThreadLocal变量作为线程内的局部变量,在多线程下可以保持独立,它存在于线程的生命周期内,可以在...

    jasperyang 评论0 收藏0
  • js 处理异步操作的几种方式

    摘要:如果我们只有一个异步操作,用回调函数来处理是完全没有任何问题的。事件监听使用事件监听的方式番禺广州上述代码需要实现一个事件监听器。只处理对象广州番禺函数将函数的自动执行器,改在语言层面提供,不暴露给用户。 概论 由于 JavaScript 是一门单线程执行的语言,所以在我们处理耗时较长的任务时,异步编程就显得尤为重要。js 处理异步操作最传统的方式是回调函数,基本上所有的异步操作都可以...

    Meils 评论0 收藏0
  • js学习之异步处理

    摘要:学习开发,无论是前端开发还是都避免不了要接触异步编程这个问题就和其它大多数以多线程同步为主的编程语言不同的主要设计是单线程异步模型。由于异步编程可以实现非阻塞的调用效果,引入异步编程自然就是顺理成章的事情了。 学习js开发,无论是前端开发还是node.js,都避免不了要接触异步编程这个问题,就和其它大多数以多线程同步为主的编程语言不同,js的主要设计是单线程异步模型。正因为js天生的与...

    VioletJack 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<