Promise异步编程解决方案

为什么要用promise?

  1. 解决回调地狱
    Promise异步编程解决方案

    
    fs.readFile(__dirname + '/data/a.txt', (err, data)=>{
        if(!err){
            console.log(data.toString());
            fs.readFile(__dirname + '/data/b.txt', (err, data)=>{
                if(!err){
                    console.log(data.toString());
                }
                fs.readFile(__dirname + '/data/cc.txt', (err, data)=>{
                    if(!err){
                        console.log(data.toString());
                    }
                });
            });
        }
    });
    
    
  2. 异步请求解决方案

概念

什么是Promise?

  1. promise,承诺。在代码中我们可以这么理解:此处我先许下个承诺,过了一定时间后我带给你一个结果。
  2. 在 Ecmascript 6 中体现出来就是一个容器对象, 一般用来封装一个异步操作

那么,在这一段时间中做什么?

  1. 我们可以进行异步操作;
    比如请求网络数据、耗时运算、读写本地文件等

Promise的三种状态

异步操作是一个无法预测的事情,要么成功,要么失败
容器内部有三种状态

  1. Pending:Promise对象实例创建时候的初始状态
  2. Fulfilled :成功的状态
  3. Rejected :失败的状态

注意: 状态不可回退

读取文件实践

创建Promise对象 (一经创建,立即执行)

  1. 细节点1
    当 Promise 对象内部的异步操作结果失败的时候,告诉 Promise 对象容器,该异步任务失败了, 其实就是将 Promise 内部的 Pending 状态改为 Rejected
  2. 细节点2
    Promise 对象内部的异步操作没有错误发生,证明成功了, 然后在这里将 Promise 内部的 Pending 状态改为 Resolved
  3. 细节点3(错误处理)
    在使用 Promise 做异步流程控制的时候,关于异常的处理可以通过在最后一个 then 之后设置一个 catch
    然后指定一个失败处理函数, 该函数可以捕获前面所有的 Promise 对象本身以及 then 内部的任务错误
    当前面任何一个发生异常,直接进入 catch,后续所有的 Promise 包括 then 不再执行

resolve 和 reject两个参数

resolve用来返回失败的结果
reject用来返回成功的结果
注意:resolve和reject只能传一个值,多个值要用对象或数组传输。

new Promise((resolve, reject)=>{
    resolve(1, 2, 222, 333);
}).then((data1,data2)=>{
    console.log(data1,data2);
});

运行结果:
Promise异步编程解决方案

三个文件异步读取

const fs = require('fs');

new Promise((resolve, reject)=>{
    fs.readFile(__dirname + '/data/a.txt', (err, data)=>{
        if(err){
            reject(err);
        }
        resolve(data);
    });
}).then((data)=>{
    console.log(data.toString());
    return new Promise((resolve, reject)=>{
        fs.readFile(__dirname + '/data/b.txt', (err, data)=>{
            if(err){
                reject(err);
            }
            resolve(data);
        });
    });
}).then((data)=>{
    console.log(data.toString());
    return new Promise((resolve, reject)=>{
        fs.readFile(__dirname + '/data/cc.txt', (err, data)=>{
            if(err){
                reject(err);
            }
            resolve(data);
        });
    });
}).then((data)=>{
    console.log(data.toString());
});

三个文件异步读取优化

const fs = require('fs');

readFile(__dirname + '/data/b.txt').then((data)=>{
    console.log(data.toString());
    return readFile(__dirname + '/data/a.txt');
}).then((data)=>{
    console.log(data.toString());
    return readFile(__dirname + '/data/cc.txt');
}).then((data)=>{
    console.log(data.toString());
});


function readFile(...args){
    return new Promise((resolve, reject)=>{
        fs.readFile(...args, (err, data)=>{
            if(err){
                reject(err);
            }
            resolve(data);
        })
    });
}

异常捕获

在链条最后加一个catch,一旦有一个地方错误,都会执行该catch

const fs = require('fs');

readFile(__dirname + '/data/b.txt').then((data)=>{
    console.log(data.toString());
    return readFile(__dirname + '/data/aa.txt');
}).then((data)=>{
    console.log(data.toString());
    return readFile(__dirname + '/data/cc.txt');
}).then((data)=>{
    console.log(data.toString());
}).catch(err => {
    console.log(err);
});


function readFile(...args){
    return new Promise((resolve, reject)=>{
        fs.readFile(...args, (err, data)=>{
            if(err){
                reject(err);
            }
            resolve(data);
        })
    });
}
上一篇:SpringBoot文件定时任务----文件监听


下一篇:微单索尼A6000使用心得