关闭

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

时间: 2018-04-16阅读: 1343标签: 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.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

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

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

关闭

实现简易版Promise

下面我们一边分析,一边实现自己的promise。首先Promise是一个构造方法,并且初始化的时候传入了一个函数作为参数,then方法很明显可以看出是Promise的实例方法,并且可以实现链式调用

Promise.resolve()详解

Promise.resolve等价于下面的写法,有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用。Promise.resolve方法的参数分成四种情况。那么 then 返回的 Promise 将会成为接受状态(resolve)

这几个Promise的输出到底是?

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

es6 Promise 的基础用法

想必接触过Node的人都知道,Node是以异步(Async)回调著称的,其异步性提高了程序的执行效率,但同时也减少了程序的可读性。如果我们有几个异步操作,并且后一个操作需要前一个操作返回的数据才能执行

10 个片段有助于我们对 Promise 的理解

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

Promise 对象的理解

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了 Promise 对象。

ES6之Promise

所谓的 promise,简单的来说就是一个容器,里面保存着某个未来才会结束的事件(也就是我们的异步操作)的结果。从语法上面来说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

关于 Promise 的 9 个提示

你可以在 .then 里面 return 一个 Promise,每次执行 .then 的时候都会自动创建一个新的 Promise,对调用者来说,Promise 的 resolved/rejected 状态是唯一的,Promise 构造函数不是解决方案,使用 Promise.resolve

这样理解 promise

官网解释 promise 表示一个异步操作的最终结果。翻译 ==可以将promise理解为一个状态机==,它存在三种不同的状态,并在某一时刻只能有一种状态,一个promise是对一个异步操作的封装

Promise中.all(), .race(), .allSettled()

从ES6 开始,我们大都使用的是 Promise.all()和Promise.race(),Promise.allSettled() 提案已经到第4阶段,因此将会成为ECMAScript 2020的一部分。Promise.all<T>(promises: Iterable<Promise<T>>): Promise<Array<T>>

点击更多...

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