1.promise的基本使用

概述:
        Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果;

1. Promise 构造函数: Promise (excutor) {};
2. Promise.prototype.then 方法;
3. Promise.prototype.catch 方法;

基本语法:

// 实例化 Promise对象
    const p = new Promise((resolve, reject) => {
        setTimeout(() => {

            // let data = "数据库中的用户数据";
            // resolve(data);

            let err = "数据读取失败";
            reject(err);

        }, 1000)
    });

    // 调用promise对象的then方法
    p.then((value) => {
        console.log(value);
    }, (reason) => {
        console.error(reason);
    })

上述代码注释部分可以自行打开进行测试。

此处补充:对象总共有三个状态:初始化,成功,失败

        在promise进行实例化时接受一个参数,参数为一个函数类型的值,该函数有两个形参,一个resolve,一个reject(可以对这两个形参任意命名,但是潜规则为resolve与reject),在函数内部封装两个异步的操作,我们在函数内部可以调用resolve与reject。

        当我们调用的为resolve,promise对象的状态变为成功,当成功之后我们可以调用对象中的then方法,then方法接受两个参数,并且两个参数都是函数类型的值。每个函数都有一个形参,成功的形参为value,失败的为reason。只要上面调的是resolve那么then执行的就一定是第一个回调函数的方法。

        当我们调用的是reject,promise对象的状态就会变为失败,这个时候调用then方法中的第二个回调函数。

        通过上述方式我们就把异步任务封装在一个promise对象当中。

2.promise读取文件

// 1.引入fs模块
const fs = require('fs');

// 2.调用方法读取文件
/* fs.readFile("./resoources/为学.md", (err, data) => {
    // 如果失败则抛出错误
    if (err) throw err;
    // 如果没有出错则输出内容
    console.log(data.toString());
}) */

// 3.使用promise封装
const p = new Promise((resolve, reject) => {
    fs.readFile("./resoources/为学.md", (err, data) => {
        // 如果失败调用reject,改变p的状态为失败
        if (err) reject(err);
        // 如果没有出错改变p的状态为成功,传入的参数为成功的值
        resolve(data);
    })
});

p.then((value) => {
    console.log(value.toString());
}, (reason) => {
    console.log("读取失败");
})

上述代码需要安装node.js,可在vscode终端运行调试

3.promise封装ajax请求

// 请求地址:https://api.apiopen.top/getJoke
const p = new Promise(function(resolve,reason){
// 原生请求
// 1、创建对象
const xhr = new XMLHttpRequest();
// 2、初始化
xhr.open("GET","https://api.apiopen.top/getJoke");
// 3、发送
xhr.send();
// 4、绑定事件,处理响应结果
xhr.onreadystatechange = function(){
// 判断状态
if(xhr.readyState == 4){
// 判断响应状态码 200-299
if(xhr.status>=200 && xhr.status<=299){
// 成功
resolve(xhr.response);
}else{
// 失败
reason(xhr.status);
}
}
}
});
运行结果:
Promise.prototype.then:
代码实现及相关说明:
p.then(function(value){
console.log(value.toString());
},function(reason){
console.log(reason); // 读取失败
})

4.promise.prototype.then方法

// 1.创建promise对象
    const p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("用户数据");
            // reject("出错啦");
        }, 1000)
    });

    // 调用then方法 then方法的返回结果是promise对象,对象状态由回调函数的执行结果决定
    // 1.如果回调函数中返回的结果是 非promise类型的属性,状态则为成功,返回值为对象的成功的值

    const result = p.then(value => {
        console.log(value);
        // 1.非promise类型的属性
        // return 111

        // 2.是promise对象
        // return new Promise((resolve, reject) => {
        //     // resolve("ok");
        //     reject("error");
        // });

        // 3.抛出错误
        throw "出错啦!"
    }, reason => {
        console.warn(reason);
    });

    console.log(result);

then的返回结果是promise对象,该对象的状态由回调函数(创建的promise对象中的resolve与reject)的执行结果决定的

1.如果回调函数中返回的结果是 非promise类型的属性(上面的return 111),状态则为成功,返回值为对象的成功的值。

2.如果回调函数中返回的结果是 promise类型的属性(上面的return new promise ()),我内部返回的promise的状态就决定了我then方法返回的promise状态

3.抛出错误的状态也是一个失败的promise。

then方法是可以链式调用的,其中reason是可以省略的。

// 链式调用
    p.then(value =>{

    }).then(value =>{
        
    })

5.promise实践练习

// 引入fs模块
const fs = require("fs");


// 使用promise实现
const p = new Promise((resolve, reject) => {
    fs.readFile('./resources/为学.md', (err, data) => {
        resolve(data.toString());
    });


});

p.then(value => {
    return new Promise((resolve, reject) => {
        fs.readFile("./resources/插秧诗.md", (err, data) => {
            resolve([value, data]);
        })
    })
}).then(value => {
    return new Promise((resolve, reject) => {
        fs.readFile("./resources/观书有感.md", (err, data) => {
            // 压入;
            value.push(data);
            resolve(value);
        })
    })
}).then(value => {
    console.log(value.join('\r\n'));
})

6.promise对象的catch方法

用于指定promise失败的一个对象的回调,类似于语法糖,then的第一个成功的函数不调用。

const p = new Promise((resolve, reject) => {
        setTimeout(() => {
            // 设置p对象的状态为失败,并设置失败的值
            reject("出错啦!")
        }, 1000)
    });

    p.catch(function (reason) {
        console.warn(reason);
    })