Promise

作者: ag4kd | 来源:发表于2019-11-08 14:32 被阅读0次

本文根据promise英文规范以及ES6源码 总结。本文拙见,欢迎斧正

这两天学习了一下 nodejs.

看到异步这一块时,百度以下Promise,发现多篇一律如下图:

image.png image.png

单线程或者多线程,跟异步没有必然的因果关系。网络和文件读写这种耗时操作才跟异步有关。多线程用来提高系统资源的利用率,异步来解决耗时任务,二者天生就没有必然的因果关。即使JS支持多线程,你也需要异步执行耗时操作,因为多线程的行为表现为异步的,你不知道这个线程啥时候执行完。

看到这两句话:

JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。

由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。

就没有再读下去的心思了,多线程只是异步操作的的一种体现方式。所以不能说单线程缺陷导致必须使用异步。

使用异步完全是因为操作耗时,会造成界面卡顿、无响应等

还是promise英文规范最靠谱。

IDE:WebStorm

ES6

前言

promise是一个健全的,可互操作的开放标准,由实现者为实现者。

promise表示异步操作的最终结果。与promise交互的主要方式是通过其then方法,该方法注册回调函数以接收的promise的最终值或promise无法实现的原因。

该规范详细描述了then方法的行为,提供了一个可交互的基础,所有承诺/A+符合承诺的实现都可以依赖于此基础来提供。因此,应该认为该规范非常稳定。虽然promise /A+组织可能偶尔会修改这个规范,对它进行一些向后兼容的小修改,以解决新发现的问题,但是我们只有在仔细考虑、讨论和测试之后,才会集成大型的或向后不兼容的修改。

历史上,promise /A+澄清了较早的promise /A提案中的行为条款,将其扩展到涵盖实际行为,并省略了未指定或有问题的部分。

最后,核心promise /A+规范不处理如何创建、实现或拒绝承诺,而是选择专注于提供一个互操作的 then方法。未来在配套规范中的工作可能会涉及这些主题。

术语

  • promise:是一个带有then方法的对象或者一个函数,其行为遵循promise /A+规范。
  • thenable:是一个对象或者一个函数,定义then方法。
  • value:一个合法的js类型的值,如undefined, a thenable, or a promise
  • exception:异常。
  • reason:绝句执行的原因。

三种状态

  • pending:可能转变完成或者拒绝。
  • fulfilled:不能转变为其他状态,只能是一个不能改变value
  • rejected:不能转变为其他状态,只能是一个不能改变reason

在这里,不能改变意味着不变的身份(即===),但并不意味着深度不变。

then方法

定义回调函数,用来接收异步任务的结果。
源码:

interface PromiseLike<T> {
    /**
     * Attaches callbacks for the resolution and/or rejection of the Promise.
     * @param onfulfilled The callback to execute when the Promise is resolved.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of which ever callback is executed.
     */
    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) =>
     TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: 
     ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): 
     PromiseLike<TResult1 | TResult2>;
}

一个promise必须提供一个then方法来访问它当前或最终的值或原因。promise的then方法接受两个参数:

promise.then(onFulfilled, onRejected)

参数含义

  • onFulfilled成功的回调,可选参数。
  • 如果不是函数,则被忽略。
  • 如果是个函数,则在promise执行成功被回调,promise’svalue会作为第一个参数传递,其实就是resolve();的一个实现方法。

  • onRejected失败的回调,可选参数,如果不是函数,则被忽略。
  • 如果是个函数,则在promise拒绝执行被回调,promise’sreason会作为第一个参数传递,其实就是reject();的一个实现方法。。

如果要回调,这两个参数必须是一个函数:

new Promise.then(function () {

},function () {
    
});

回调时机

onFulfilledonRejected 只有在执行环境堆栈仅包含平台代码时才可被调用!说白了,就是通过resolve或者reject``,来执行回调逻辑。

正常业务逻辑下需要调用resolve("参数");方法去触发回调函数onFulfilled的执行;异常逻辑需要throw一个异常Error或者通过reject();方法来触发onRejected的执行。否则不执行回调!

then一定返回一个promise

实现链式调用的基础

promise2 = promise1.then(onFulfilled, onRejected);

简单的案例

then源码声明:

 /**
     * Attaches callbacks for the resolution and/or rejection of the Promise.
     * @param onfulfilled The callback to execute when the Promise is resolved.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of which ever callback is executed.
     */
    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) =>
     TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: 
     ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): 
     Promise<TResult1 | TResult2>;

catch 源码(声明):


    /**
     * Attaches a callback for only the rejection of the Promise.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of the callback.
     */
    catch<TResult = never>(onrejected?: ((reason: any) => 
    TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;

没有出现错误或异常的代码

function promise() {
    let promise = new Promise(function (resolve, reject) {
        console.log("处理具体业务");
        resolve("参数");//
    }).then(function (value) {
        console.log("处理成功 " + value);
    }, function () {
        console.log("处理失败");
    }).catch(function () {
        console.log("处理异常");
    });
}

promise();
image.png

出现错误或异常的代码

function promise() {
    let promise = new Promise(function (resolve, reject) {
        try {
            console.log("处理具体业务");
            ass();//未定义函数
            console.log("处理具体业务,异常代码之后");
            resolve("参数");//
        } catch (e) {
            throw new Error("dddd");
            // reject();
        }
    }).then(function (value) {
        console.log("处理成功 " + value);
    }, function () {
        console.log("处理失败");
    }).catch(function () {
        console.log("处理异常");
    });
}
promise();

程序调用了一个未定义的函数ass();,然后,走catch{}块,在这个捕获异常的代码块里面,执行reject();或者抛出一个错误,如果then方法的第二个参数是函数,则会走这个回调函数,如果没有定义第二个回调函数而是定义了一个catch代码块,则会走catch代码块,如果即定义了回调函数,又调用了异常处理函数catch代码块,则只会有回调函数,如果二者都没有,则程序会报错,以下是未实现回调函数而调用了异常处理函数。

本质上,是有调用了只有声明而没有实现的函数。

1、异常没有被开发者实现:


image.png

2、reject();没有被开发者实现:

image.png

总之,至少要有一个能够异常或者的回调逻辑。

可以被回调多次的then

function doing(value) {
    return new Promise(function (resolve, reject) {
        try {
            console.log(value);
            resolve(value);//
            // resolve();//
        } catch (e) {
            // throw new Error("dddd");
            reject(value);
        }
    });
}

function do_something_wrong(value) {
    return new Promise(function (resolve, reject) {
        try {
            console.log(value + "级业务");
            // ass();
            // reject("业务逻辑异常");
            resolve(value);//
            // resolve();//
        } catch (e) {
            // throw new Error("dddd");
            reject(value);
        }
    });
}

function promise() {
    let promise = new Promise(function (resolve, reject) {
        try {
            console.log("一级业务");
            ass();
            console.log("处理具体业务,异常代码之后");
            resolve(1);//
        } catch (e) {
            // throw new Error("dddd");
            reject(2);
        }
    }).then(function (value) {
        doing("二级业务");
    }, function (error) {
        do_something_wrong("二级业务----处理一级异常");
    }).then(function (value) {
        doing("三级业务");
    }, function (value) {
        do_something_wrong("三级业务----处理一级异常");
    }).then(function (value) {
        doing("四级业务");
    }, function (value) {
        do_something_wrong("四级业务----处理一级异常");
    }).then(function (value) {
        doing("五级业务");
    }, function (value) {
        do_something_wrong("五级业务----处理一级异常");
    }).then(function (value) {
        doing("六级业务");
    }, function (value) {
        do_something_wrong("六级业务----处理一级异常");
    });
    return promise;
}

promise();
image.png

英文原文说:

If/when promise is fulfilled, all respective onFulfilled callbacks must execute in the order of their originating calls to then.

If/when promise is rejected, all respective onRejected callbacks must execute in the order of their originating calls to then.
  • promise 成功执行时,所有 onFulfilled 需按照其链式调用的顺序依次回调。
  • promise 被拒绝执行时,所有的 onRejected 需按照其链式调用的顺序依次回调。

相关文章

网友评论

      本文标题:Promise

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