• 基于Node的Promise使用介绍


    异步操作常见语法:

    (1)基于事件的监听机制,常见的如在dom节点上绑定click、blur等事件:

    (2)基于回调。先调用外部函数,例如下面的$.ajax,然后再传入一个回调函数,当外部函数执行完毕后,回调函数就会被触发

    promise产生的原因

    (1)解决同步问题
    (2)解决无穷回调

    在浏览器中,异步操作主要以事件为主,回调请求一般出现在网络请求或文件API中。

    当node.js出现后,对于异步的依赖进一步加剧,因为Node的招牌就是无阻塞高并发,自然而然异步操作就是这一特性的重要保障。

    当node.js接受一个用户请求之后,若此请求中包含了耗时的数据库操作,那么node在发起数据库操作之后,会暂时讲用户请求挂起,并继续接收请他请求(高并发),当数据库运行完毕返回结果后,之前挂起的请求就会重新被唤醒,接着后续的操作。

    在上述过程中,会大量依赖回调函数。当业务逻辑复杂时,就会陷入无穷回调的窘境里:

    这样的代码在可阅读性和维护性上都极差

    异步回调的问题

    (1)嵌套层次深,难以维护

    (2)无法正常的使用return和throw。由于回调函数和外部函数不处于用一个的执行栈,所以常规的try/catch 方法没有办法捕获到回调函数中的异常,只能通过return callback(err)的方法返回错误

    (3)定义的全局变量在回调函数中的状态不确定,尤其是当同一个全局变量存在于多个回调函数中时,由于回调函数触发的时机不可控,就导致了此全局变量变化不可控的情况。

    promise简介

    在使用promise的时候,首先要初始化一个promise实例,需要向里面传入一个参数(函数),此函数称为执行器。执行器里传入了两个参数——resolve和reject。我们可以把耗时很长的操作放在执行器里执行。当数据执行完毕且正确时,就会调用resolve()方法,如果执行错误,就会调用reject方法。

    当这两个函数执行完毕后,就会去改变promise的状态,紧接着就会去调用then函数里的两个处理函数。若执行器调用了resolve函数,则then里第一个参数函数被回调;若执行器执行了reject方法,则then里第二个参数函数被回调

    promise详解

    以上,promise只是一个代理对象,它和原先要进行的操作并无关系,同时它只引入了一个回调,避免更多的回调,可以以此把其他回调展开,变成基于promise的回调

    promise状态

    (1)pending[待定]初始状态:实例化之后的状态

    (2)fulfilled[实现]操作成功:当执行完毕后,调用resolve时

    (3)rejected[被否决]:操作失败

    当promise状态发生改变后,就会触发.then()里得到的响应函数处理后续步骤。当promise状态改版后就不会再改变了。

    最简单的范例

    两步定时执行:

    console.log('here we go');
    new Promise( resolve => {
        setTimeout( () => {
            resolve('hello');
        }, 2000);
    })
        .then( value => {
            console.log(value);
            return new Promise( resolve => {
                setTimeout( () => {
                    resolve('world');
                }, 2000);
            });
        })
        .then( value => {
            console.log( value + ' world');
        });
    

    此例子是演示的promise最常用从场景——多次回调

    对已完成的promise进行then操作

    
    console.log('start');
    
    let promise = new Promise(resolve => {
        setTimeout(() => {
            console.log('the promise fulfilled');
            resolve('hello, world');
        }, 1000);
    });
    
    setTimeout(() => {
        promise.then( value => {
            console.log(value);
        });
    }, 3000);
    

    此例子展示了promise作为队列的特性——我们在任何地方生成了一个promise队列之后,我们可以把它作为一个变量传递到其他地方

    如果在promise中不返回新的promise

    console.log('here we go');
    new Promise(resolve => {
        setTimeout( () => {
            resolve('hello');
        }, 2000);
    })
        .then( value => {
            console.log(value);
            console.log('everyone');
            (function () {
                return new Promise(resolve => {
                    setTimeout(() => {
                        console.log('Mr.Laurence');
                        resolve('Merry Xmas');
                    }, 2000);
                });
            }());
            return false;
        })
        .then( value => {
            console.log(value + ' world');
        });
    

    最终返回:

    本例中在第一个then里没有返回一个新的值,而是返回了一个立即执行的函数,在此自执行函数里返回了一个promise。最外层的promise不会等待里面的自执行函数,而是会在return false的作用下立即调用.then,此时then里的value就对应‘false’。

    .then()

    说明

    • .then()接受两个函数作为参数,分表代表fulfilled状态下响应函数和rejected状态下的响应函数。

    • 执行.then之后会返回一个新的promise实例,多以可以在.then继续进行链式调用 。

    • 当前面的promise状态改变时,.then根据其最终状态,选择特定的状态响应函数执行。如果

    • 状态响应函数可以返回新的promise,或其他值。

    • 如果返回新的promise,那么下一级.then()会在新promise状态改变之后执行。

    • 如果返回其他任何值,则会立即执行下一级.then()

    .then()的嵌套

    • 因为.then()返回的还是promise的实例,所以会等里面的.then()执行完,再执行外面的。

    测试

    错误处理

    当我们在catch中处理错误时,仍然会返回promise实例。

    常用函数

    promise.all()批量执行

    .map()连用

    把一组操作转化为promise集体的一个状态

    实现队列

    有时候我们不希望所有动作一起发生,而是按照一定顺序,逐个进行。

    Promise.resolve

    Promise.reject()

    Promise.race()

    把回调包装成promise

    async/await


     

  • 相关阅读:
    工作感悟
    9/10记事
    总结几份工作的感悟
    四次原则
    在UC浏览器上很炫的一个效果
    php跨服务器传递对象
    wdlinux一键安装包
    手机号码4位隐藏
    php中英文字符串转字母转大小写
    MySQL添加用户、删除用户与授权
  • 原文地址:https://www.cnblogs.com/wjlbk/p/12633342.html
Copyright © 2020-2023  润新知