简单模仿实现 Promise 的异步模式

时间: 2018-04-16阅读: 1107标签: Promise

这篇文章是考虑如何自己实现一个简单 Promise,用以理解 Promise。


需求

实现如下要求:

doSomething().then(function(res){ // res 是 doSomething() 的结果
    doSomethingElse(res);
});


Promise 写法

使用原生Promise方法,代码会如下:

function doSomething() {
    var result = 1;
    return new Promise(function (resolve) {
        resolve(result);
    });
}
function doSomethingElse(arg) {
    console.log(arg);
}
doSomething().then(function (res) {
    doSomethingElse(res);  // 输出 1,然后返回结果是一个 Promise 对象,可以继续链式调用 then 方法
});


仿Promise 写法

接下来仿制一下这个 Promise 函数: 
FPromise 是有状态的(Pending、Fulfilled、Rejected)

function FPromise(fn) {
    var status = "Pending"; // 初始状态
    var res = null;

    function handleFulfilled(value) {
        status = "Fulfilled";
        res = value;
    }

    function handleRejected(reason) {
        status = "Rejected";
        res = reason;
    }

    function handle(handler) {
        var callback = null;
        if (status == "Fulfilled") {
            callback = handler.onFulfilled;
        } else if (status == "Rejected") {
            callback = handler.onRejected;
        }

        callback(res);
    }

    this.then = function (onFulfilled, onRejected) {
        handle({
            onFulfilled: onFulfilled,
            onRejected: onRejected
        })

    }

    fn(handleFulfilled, handleRejected);
}


和原生 Promise的调用方法一样,把 Promise 换成 FPromise 如下:

function doSomething() {
    var result = 1;
    return new FPromise(function (resolve) { // 和 Promise 一样调用
        resolve(result);
    });
}
function doSomethingElse(arg) {
    console.log(arg);
}
doSomething().then(function (res) {
    doSomethingElse(res); // 输出 1,但是没有返回结果,无法继续链式调用 then 方法
});


使用 reject 的情况如下:

function doSomething() {
    var result = 2;
    return new FPromise(function (resolve, reject) {
        if (result == 1) {
            resolve(result);
        } else {
            reject("error");
        }
    });
}
doSomething().then(null, function (reason) {
    console.log(reason) // 输出 ‘error’
});


上面的 FPromise 函数无法进行链式调用,需要在 then 方法中再返回一个新的 FPromise,继续修改之

function FPromise(fn) {
    var status = "Pending"; // 初始状态
    var res = null;

    function handleFulfilled(value) {
        status = "Fulfilled";
        res = value;
    }

    function handleRejected(reason) {
        status = "Rejected";
        res = reason;
    }

    function handle(handler) {

        var callback = null;
        if (status == "Fulfilled") {
            callback = handler.onFulfilled;
        } else if (status == "Rejected") {
            callback = handler.onRejected;
        }


        if (callback) {
            var tmp = callback(res);
            if (status == "Fulfilled") { 
                handler.resolve && handler.resolve(tmp); // 第二个 FPromise 里面的参数是第一个 FPromise 执行的结果
            } else if (status == "Rejected") {
                handler.reject && handler.reject(tmp);
            }
        }
    }

    this.then = function (onFulfilled, onRejected) {
        return new FPromise(function (resolve, reject) {
            handle({
                onFulfilled: onFulfilled,
                onRejected: onRejected,
                resolve: resolve, // 相当于下一个promise 的onFulfilled 方法
                reject: reject
            })
        });
    }

    fn(handleFulfilled, handleRejected);
}


链式调用 then 方法如下,

function doSomething() {
    var result = 1;
    return new FPromise(function (resolve) {
        resolve(result);
    });
}
function doSomethingElse(arg) {
    console.log(arg);
}
doSomething().then(function (res) {
    doSomethingElse(res); // 输出 1
    return res;
}).then(function (res) {
    console.log(res + 1); // 输出 2
});


总结

本文实现的方法只能用于参考Promise的原理,还有很多特性没有实现,比如 race,all 方法的实现。一个更好的实现参考https://github.com/LucaslEliane/fake-promise/blob/master/fake-promise.jsMDN 文档中推荐的是 Promise-Polyfill

如何更好的使用Promise可以参考这个文章https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html

来源:https://blog.csdn.net/YZ0826/article/details/79943278


站长推荐

1.阿里云: 本站目前使用的是阿里云主机,安全/可靠/稳定。点击领取2000元代金券、了解最新阿里云产品的各种优惠活动点击进入

2.腾讯云: 提供云服务器、云数据库、云存储、视频与CDN、域名等服务。腾讯云各类产品的最新活动,优惠券领取点击进入

3.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/640

你真的懂Promise吗

在异步编程中,Promise 扮演了举足轻重的角色,比传统的解决方案(回调函数和事件)更合理和更强大。可能有些小伙伴会有这样的疑问:2020年了,怎么还在谈论Promise?

Js Promise的并行和串行

Promise.all是所有的Promise执行完毕后(reject|resolve)返回一个Promise对象。最近在开发一个项目中,需要等接口拿到全部数据后刷新页面,取消loding效果

实现Promise的first等各种变体

本篇文章主要是想通过ES6中Promise提供的几个方法,来实现诸如first、last、none、any等各种变体方法!在标准的ES6规范中,提供了Promise.all和Promise.race两种

这 10 个片段,有助于你理解 ES 中的 Promise

在开发中,了解 JavaScript 和 Promise 基础,有助于提高我们的编码技能,今天,我们一起来看看下面的 10 片段,相信看完这 10 个片段有助于我们对 Promise 的理解。

纯手写Promise,由浅入深

首先我们应该知道Promise是通过构造函数的方式来创建的(new Promise( executor )),并且为 executor函数 传递参数:再来说一下Promise的三种状态: pending-等待, resolve-成功, reject-失败, 其中最开始为pending状态

promise 实现(es6 完整源码)

Promise 内部维护着三种状态 pending、fulfilled 和 rejected,状态只能从 pending 转变到 fulfilled,或从 pending 转变到 rejected 且该转变不可逆。Promise 主要提供了三个实例方法 then,catch,finally,和4个静态方法 resolve,reject,all,race。

ES6 Promise

最近一段时间在重温ES6,Promise应该是是ES6新特性中非常重要的一部分内容。其实Promise在我日常开发中已经用得比较多,但大多数时候只是知道Promise可以用来实现异步编程,也只限于单纯地会用罢了,并没有时间深入去学习过

promise

Promise的构造函数接收一个参数,是函数,并且传入两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数

自己动手实现一个Promise

Promise 对象是一个代理对象,被代理的值在Promise对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值

这几个Promise的输出到底是?

我们使用构造函数方法创建一个Promise实例,立即使用 reject 回调触发一个错误。catch处理程序的工作方式类似于DOM的 .addeventlistener(事件、回调)或事件发射器的 .on(事件、回调),其中可以添加多个回调。每个回调都具有相同的参数。

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!

文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯幽默笑话段子句子语录成语大全运营推广