推导产生的promise

需求:封装一个方法,传入一个文件的路径,这个方法读取文件并且把内容返回给我

目录结构
|–1.txt
|–2.txt
|–3.txt
|–fun.js

引入相关的 node 模块 fs 和 path (node.js API里有说明)

const fs = require('fs')
const path = require('path')

读文件代码

fs.readfile(path(__diename,'./1.txt'),'utf-8',funciton(err.data){
    if(err){
        return err
    }
    return data
})

封装起来成一个函数

function getFile(filePath){
    fs.readfile(filePath,'utf-8',funciton(err.data){
    if(err){
        return err
    }
    return data
})
}
var cont = getFile(.....)
console.log(cont)

以上的程序执行会报undefined,因为读文件是个异步操作,fs.readfile 直接丢进队列里,打印结果的时候,文件读取还没完成

那么怎么解决呢?
封装函数的时候,定义一个回调函数,
让异步里面的结果出来后,传给回调函数,我们从回调函数里拿要的值

function getFile(filePath,callback){    //  1
    fs.readfile(filePath,'utf-8',funciton(err.data){     //这里有错误,要用es6箭头函数,不然this有问题?需要验证
    if(err){
        return callback(err)
    }
    callback(data)     //   2
})
}
getFile('./1.txt',function(data){
    console.log(data)                  //    3
})

以上封装也是不完善的,为什么呢?因为回调里面只接收一个参数,不一定知道里面的参数是成功的还是失败的

那么这样,给回调函数规定有2个参数,第一个是失败,第二个是成功
如果成功了,回调的第一个参数就是null
如果失败了,回调的第二个参数就是null

function getFile(filePath,callback){    
    fs.readfile(filePath,'utf-8',funciton(err.data){         //这里有错误,要用es6箭头函数,不然this有问题?需要验证
    if(err){
        return callback(err)
    }
    callback(null,data)    
})
}
getFile('./1.txt',function(err,data){
    if(err){
        return console.log(err)    
        }
    console.log(data)                  
})

这样还不完善,为什么呢?因为使用者看到这个函数 function getFile(filePath,callback) 是不知道回调里面有2个参数的,我们自己写的知道,使用者不知道
改进,给方法增加2个回调,一个成功的,一个失败的,这样一来,使用者就知道了

function getFile(filePath,succCb,errCb){    
    fs.readfile(filePath,'utf-8',funciton(err.data){         //这里有错误,要用es6箭头函数,不然this有问题?需要验证
    if(err){
        return errCb(err)
    }
   succCb(data)    
})
}
getFile('./1.txt',function(suc){
    console.log(suc)          
},function(err){
    console.log(err) 
})

一个需求:先读文件1,再度文件2,再度文件3,这就产生了回调地狱

getFile('./1.txt',function(suc){
    console.log(suc)     
         getFile('./2.txt',function(suc){
         console.log(suc)     
             getFile('./3.txt',function(suc){
                console.log(suc)     
         })
    })
})

使用es6中的promise来解决回调地狱,把一层又一层的嵌套,改变成串联,翻译就是连写

打印

console.dir(Promise)


ƒ Promise()
    all:ƒ all()
    arguments:(...)
    caller:(...)
    length:1
    name:"Promise"
    prototype:Promise {constructor: ƒ, then: ƒ, catch: ƒ, finally: ƒ, Symbol(Symbol.toStringTag): "Promise"}
    race:ƒ race()
    reject:ƒ reject()
    resolve:ƒ resolve()
    Symbol(Symbol.species):(...)
    get Symbol(Symbol.species):ƒ [Symbol.species]()
    __proto__:ƒ ()
    [[Scopes]]:Scopes[0]

Promise 里面有 prototype 里面有 then ,就是说,new 出来的 Promise 都可以使用 then 属性

既然 Promise 是一个实例,是一个异步操作,那么结果就只有两种状态:成功、失败。

由于reject()是一个异步操作,内部的操作,是无法通过 return 返回的(上面的读文件的例子说明了),这个时候就只能借助回调函数来拿到成功或失败的值。

成功了会调用 resolve()
失败了会调用 reject()

我们在 new 出来的 Promise 实例,调用 then() 方法,预先为这个 Promise 异步操作,指定成功和失败的回调函数
Promise 内部的 resolve() 和 reject() 是形参,.then()出来的是实参

怎么在 Promise 里写异步操作?
在一个 funtion 里写具体的异步操作

new Promise(function(resolve,reject){
    在此处函数里写的就是异步操作
})


 Promise 一个特点,只要 new 出来,就会执行,如下也会执行
var promise = new Promise(function(resolve,reject){
    在此处函数里写的就是异步操作
})

这样不好,我需要在想用的时候才让它执行,那怎么办?满足这种要求的,只有函数,函数在调用的时候才执行,那么,把

promise 代码放进一个函数就可以了

function getText(){
    var promise = new Promise(function(resolve,reject){
        在此处函数里写的就是异步操作
    })
}
getText()

配合.then使用

.then里面,成功的回调必须传,失败的可以省略
function getText(){
    var promise = new Promise(function(resolve,reject){
        fs.readfile('./1.txt','utf-8',(data,err)=>{
            if(err) return reject(err)
            return resolve(data)
        })
    })
    return promise
}
getText().then(
    function(data){
        console.log(data)
    },
    function(err){
        console.log(err)
    }
)

想连续读取文件1、2、3

getText('1/txt').then(
    function(data){
        console.log(data)
        return getText('2/txt')
    }
).then(
    function(data){
        console.log(data)
        return getText('3/txt')
    }
).then(
    function(data){
        console.log(data)
    }
)

如果前面的异步失败,那么后面的都不会执行,怎么解决这个问题
给异步加上失败的回调
在失败的回调里返回下一个异步操作

getText('1/txt').then(
    function(data){
        console.log(data)
        return getText('2/txt')
    },
    function(err){
        console.log(err)
        return getText('2/txt')
    }
).then(
    function(data){
        console.log(data)
        return getText('3/txt')
    },
    function(err){
        console.log(err)
        return getText('3/txt')
    }
).then(
    function(data){
        console.log(data)
    }
)

.catch 错误捕获处理
就是说,任何一个错误出现了,马上中止执行,跳进catch中执行

getText('1/txt').then(
    function(data){
        console.log(data)
        return getText('2/txt')
    }
).then(
    function(data){
        console.log(data)
        return getText('3/txt')
    }
).then(
    function(data){
        console.log(data)
    }
).catch(err){
    console.log(err)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值