• Promise面试题


    Promise的介绍和优点

    es6中的promise时异步编程的一种方案. 从语法上来讲, promise是一个对象, 它可以获取异步操作的消息

    promise对象, 可以将异步操作以同步的流程表达出来

    好处:

    可以很好的解决回调地狱问题 (避免了层层嵌套的回调函数)

    语法非常简洁. promise对象提供简介的api, 使得控制异步操作更加容易

    Promise的基本用法

    1 new实例化一个promise对象, promise的构造函数中传递一个参数, 是一个函数, 该函数用于处理异步任务

    2 传入两个参数: resolve和reject, 分别代表异步执行成功后的回调函数和失败后的回调函数

    3 通过promise.then()处理返回结构

    实例

    // 第一步:model层的接口封装
    const promise = new Promise((resolve, reject) => {
        // 这里做异步任务(比如ajax 请求接口。这里暂时用定时器代替)
        setTimeout(function() {
            var data = { retCode: 0, msg: 'qianguyihao' }; // 接口返回的数据
            if (data.retCode == 0) {
                // 接口请求成功时调用
                resolve(data);
            } else {
                // 接口请求失败时调用
                reject({ retCode: -1, msg: 'network error' });
            }
        }, 100);
    });
    
    // 第二步:业务层的接口调用。这里的 data 就是 从 resolve 和 reject 传过来的,也就是从接口拿到的数据
    promise.then(data => {
        // 从 resolve 获取正常结果
        console.log(data);
    }).catch(data => {
        // 从 reject 获取异常结果
        console.log(data);
    });
    

    Promise对象的3个状态

    初始化状态(等待状态): pending

    成功状态: fullfilled

    失败状态: rejected

    (1)当new Promise()执行之后,promise对象的状态会被初始化为pending,这个状态是初始化状态。new Promise()这行代码,括号里的内容是同步执行的。括号里定义一个function,function有两个参数:resolve和reject。如下:

    • 如果请求成功了,则执行resolve(),此时,promise的状态会被自动修改为fullfilled。
    • 如果请求失败了,则执行reject(),此时,promise的状态会被自动修改为rejected

    (2)promise.then()方法,括号里面有两个参数,分别代表两个函数 function1 和 function2:

    • 如果promise的状态为fullfilled(意思是:如果请求成功),则执行function1里的内容
    • 如果promise的状态为rejected(意思是,如果请求失败),则执行function2里的内容

    Promise处理多次ajax请求(链式调用)

    promise可以把原本的多层嵌套调用改为链式调用

    /*
    	基于Promise发送Ajax请求
    */
    function queryData(url) {
        var promise = new Promise((resolve, reject) => {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function() {
                if (xhr.readyState != 4) return;
                if (xhr.readyState == 4 && xhr.status == 200) {
                    // 处理正常情况
                    resolve(xhr.responseText); // xhr.responseText 是从接口拿到的数据
                } else {
                    // 处理异常情况
                    reject('接口请求失败');
                }
            };
            xhr.responseType = 'json'; // 设置返回的数据类型
            xhr.open('get', url);
            xhr.send(null); // 请求接口
        });
        return promise;
    }
    // 发送多个ajax请求并且保证顺序
    queryData('http://localhost:3000/api1')
        .then(
            data1 => {
                console.log(JSON.stringify(data1));
                // 请求完接口1后,继续请求接口2
                return queryData('http://localhost:3000/api2');
            },
            error1 => {
            	console.log(error1);
            }
        )
        .then(
            data2 => {
                console.log(JSON.stringify(data2));
                // 请求完接口2后,继续请求接口3
                return queryData('http://localhost:3000/api3');
            },
            error2 => {
            	console.log(error2);
            }
        )
        .then(
            data3 => {
                // 获取接口3返回的数据
                console.log(JSON.stringify(data3));
            },
            error3 => {
            	console.log(error3);
            }
    	);
    

    Promise的常用API: 实例方法

    promise.then(): 获取异步任务的正常结果

    promise.catch(): 获取异步任务的异步结果

    promise.finaly(): 异步任务无论成功与否, 都会执行

    queryData()
        .then(data => {
            // 从 resolve 获取正常结果
            console.log('接口请求成功时,走这里');
            console.log(data);
        })
        .catch(data => {
            // 从 reject 获取异常结果
            console.log('接口请求失败时,走这里');
            console.log(data);
        })
        .finally(() => {
        	console.log('无论接口请求成功与否,都会走这里');
        });
    
    queryData()
        .then(
            data => {
                // 从 resolve 获取正常结果
                console.log('接口请求成功时,走这里');
                console.log(data);
            },
            data => {
                // 从 reject 获取异常结果
                console.log('接口请求失败时,走这里');
                console.log(data);
            }
        )
        .finally(() => {
        	console.log('无论接口请求成功与否,都会走这里');
    });
    

    Promise的常用API: 对象方法

    promise.all(): 并发处理多个异步任务, 所有任务都执行成功, 才能得到结果.

    promise.race(): 并发处理多个异步处理, 只要一个任务执行成功, 就能得到结果

    /*
    封装 Promise 接口调用
    */
    function queryData(url) {
        return new Promise((resolve, reject) => {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function() {
                if (xhr.readyState != 4) return;
                if (xhr.readyState == 4 && xhr.status == 200) {
                    // 处理正常结果
                    resolve(xhr.responseText);
                } else {
                    // 处理异常结果
                    reject('服务器错误');
                }
            };
            xhr.open('get', url);
            xhr.send(null);
        });
    }
    
    var promise1 = queryData('http://localhost:3000/a1');
    var promise2 = queryData('http://localhost:3000/a2');
    var promise3 = queryData('http://localhost:3000/a3');
    
    Promise.all([promise1, promise2, promise3]).then(result => {
    	console.log(result);
    });
    
    /*
    封装 Promise 接口调用
    */
    function queryData(url) {
        return new Promise((resolve, reject) => {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function() {
                if (xhr.readyState != 4) return;
                if (xhr.readyState == 4 && xhr.status == 200) {
                    // 处理正常结果
                    resolve(xhr.responseText);
                } else {
                    // 处理异常结果
                    reject('服务器错误');
                }
            };
            xhr.open('get', url);
            xhr.send(null);
        });
    }
    
    var promise1 = queryData('http://localhost:3000/a1');
    var promise2 = queryData('http://localhost:3000/a2');
    var promise3 = queryData('http://localhost:3000/a3');
    
    Promise.race([promise1, promise2, promise3]).then(result => {
    	console.log(result);
    });
    
  • 相关阅读:
    godaddy 亚太机房 更换 美国机房 全过程(图)
    博客园设置访问密码
    GoDaddy Linux主机支持机房的更换
    今天电信宽代终于装上光纤了,升级或安装光纤需购光猫,可以自购。我来扫盲一下
    我来科普一下为毛很多人升级了20M的电信光纤宽带反而感觉速度更卡了
    百度浏览器使用率统计
    hdu 1281
    C#基于SMTP协议和SOCKET通信,实现邮件内容和附件的发送,并可隐藏收件人
    如何处理标注打架
    提高你的Java代码质量吧:谨慎包装类型的比较
  • 原文地址:https://www.cnblogs.com/bnzw/p/14207838.html
Copyright © 2020-2023  润新知