当前位置: 首页 > 工具软件 > node-promise > 使用案例 >

NodeJS 1-01-04_Promise

公羊灿
2023-12-01

通过回调函数获取函数的执行结果:

1、sum定义三个形参分别为a、b、cb(回调函数callback)。给sum传递三个实参分别为123、456、function函数, 则 cb 即为第三个参数;

2、调cb()就是在调function(){ }这个函数,将a+b作为回调函数的参数传递给function(){ },定义形参result接收这个变量;

3、将result作为结果输出。

function sum(a,b,cb){
    cb(a+b)
}

sum(123,456,function(result){
    console.log(result)
})

注:下述的return是匿名函数的返回值,并不是sum的返回值

function sum(a, b, cb) {
    setTimeout(() => {
        return a + b
    }, 1000)
}

所以需要通过回调函数来返回,即为回调函数的作用。

function sum(a, b, cb) {
    setTimeout(() => {
        cb(a + b)
    }, 1000)
}

node.js         通过异步方式解决同步的问题 

什么是异步?

一段代码执行不会影响到其他程序

异步的问题?

异步的代码无法通过return来设置返回值

特点?

1、不会阻塞其他代码执行        2、需要通过回调函数来返回结果

基于回调函数的异步带来的问题?

1、代码的可读性差        2、可调式性差

解决问题:

需要一个东西,可以代替回调函数来给返回结果。Promise!!!

Promise 是一个可以用来存储数据的对象

Promise存储数据的方式比较特殊,这种特殊方式使得Promise可以用来存储异步调用的数据。

注:现实生活:1、点菜   2、厨师做菜   3、吃。


异步调用必须要通过回调函数来返回数据,当我们进行一些复杂的调用时,会出现“回调地狱

Promise:可以帮助解决异步中回调函数的问题,是一个用来存储数据的容器,它拥有着一套特殊的存储数据的方式,这个方式使它可以存储异步调用的结果。


创建Promise时,构造函数中需要函数作为参数。

const promise = new Promise(() => {})

Promise构造函数的回调函数,它会在创建Promise时调用,调用时会有两个参数传递进去

const promise = new Promise((resolve, reject) => {}

resolve和reject是两个函数,通过这两个函数可以向Promise中存储数据;

resolve在执行正常时存储数据,reject在执行错误时执行数据。

const promise = new Promise((resolve, reject) => {
    reject("哈哈") //错误时存储,需抛出异常throw new Error("哈哈,出错了")
    resolve("resolve返回的数据")
})
console.log(promise)

通过函数来向Promise中添加数据,好处就是可以用来添加异步调用的数据;

第一个匿名函数在2秒后执行,第二个匿名函数在3秒后执行,“哈哈”被存入到resolve中。

const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("哈哈")
    }, 2000)
})

setTimeout(() => {
       console.log(promise)
    }, 3000)

从Promise中读取数据

可以通过Promise的实例方法then来读取Promise中存储的数据

then需要两个回调函数作为参数,回调函数用来获取Promise中的数据

通过resolve存储的数据,会调用第一个函数返回,可以在第一个函数中编写处理数据的代码

通过reject存储的数据 或者出现异常时,会调用第二个函数返回数据,可以在第二个函数中编写处理异常的代码

注:resolve和reject是Promise创建的,用来存数据的

        result和reason是自己创建的,用来取数据的

const promise = new Promise((resolve, reject) => {
        //throw new Error("哈哈,出错了")
        //resolve("resolve返回的数据")
        reject("reject返回的数据")
})

promise.then((result) => {
    console.log("1", result);
}, (reason) => {
    console.log("2", reason);
})

Promise中维护了两个隐藏属性:PromiseResult        PromiseState

PromiseResult:用来存储数据

PromiseState:记录Promise的状态(三种状态)

注:state只能修改一次,修改以后永远不会在变

        pending (进行中)

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("哈哈")
    }, 2000)
})
console.log(promise2);

        fulfilled (完成) 通过resolve存储数据

const promise2 = new Promise((resolve, reject) => {
    resolve("哈哈")
})
console.log(promise2);

        rejected (拒绝,出错了) 出错了或通过reject存储数据时

const promise2 = new Promise((resolve, reject) => {
    reject("哈哈")
})
console.log(promise2);

流程:

当Promise创建时,PromiseState初始值为pending

当通过resolve存储数据时,PromiseState 变为fulfilled,PromiseResult变为存储的变量

当通过reject存储数据或出错时,PromiseState 变为rejected,PromiseResult变为存储的变量 或 异常对象


当我们通过then读取数据时,相当于为Promise设置了回调函数:

注:如同DOM中为响应函数绑定事件

如果PromiseState变为fulfilled,则调用then的第一个回调函数来返回数据;如果PromiseState变为reject,则调用then的第二个回调函数来返回数据。

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("哈哈")
    }, 2000)
})

promise2.then(result => {
    console.log(result);
}, reason => {
    console.log("出错了");
})

catch()

catch() 用法和then类似,但是只需要一个回调函数作为参数

catch()中的回调函数只会在Promise被拒绝时才会调用

catch()相当于 then(null,reason =>{})

注:catch() 就是一个专门处理Promise异常的方法

const promise2 = new Promise((resolve, reject) => {
    reject("哈哈")
})

promise2.catch(reason =>{
    console.log(2222);
})

finally()

无论是正常存储数据还是出现异常,finally总会执行,但是finally的回调函数中不会接收数据

finally()通常用来编写一些无论成功与否都要执行的代码

const promise2 = new Promise((resolve, reject) => {
    resolve("哈哈")
    //reject("哈哈")
})

promise2.finally(() => {
    console.log("没有什么能够阻挡");
})

回调地狱:

function sum(a, b, cb) {
    setTimeout(() => {
        cb(a + b)
    }, 1000)
}

const result = sum(123, 456, (result) => {
    sum(result, 7, (result) => {
        sum(result, 8, (result) => {
            sum(result, 9, (result) => {
                sum(result, 10, (result) => {
                    console.log(result);
                })
            })
        })
    })
})

解决回调地狱问题

定义一个异步函数sum()

将结果a+b通过resolve存储到Promise中

注:当返回值是Promise对象时不用接收返回值

function sum(a, b) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a + b)
        }, 1000)
    })
}

sum(123,456).then((result)=>{
    console.log(result)
})

注:promise中的 then (return new Promise())  ,catch (return new Promise()) , finally ,这三个方法都会返回一个新的promise;Promise中存储的是回调函数的返回值 但是 finally 的返回值不会存储到新的Promise中

p2中回调函数的返回值会成为新的promise中的result

then中的代码是异步调用

const promise = new Promise((resolve, reject) => {
    resolve("每周一到周五19点");
})

const p2 = promise.then((result) => {
    console.log("回调函数", result);
    return "锄禾日当午"
})

setTimeout(() => {
    console.log(p2);
}, 1000)
function sum(a, b) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a + b)
        }, 1000)
    })
}

sum(123, 456)
    .then(result => result + 7)
    .then(result => result + 8)
    .then(result => result + 9)
    .then(result => console.log(result))

无异常会跳过catch,只执行then

const promise = new Promise((resolve, reject) => {
    resolve("每周一到周五19点");
})

promise
    .then(r => "哈哈")
    .catch(r => console.log("异常处理",+r))
    .then(r => console.log("第二个then",r))

有异常会跳过第一个catch之前的所有then,只执行catch和之后的then

const promise = new Promise((resolve, reject) => {
    reject("每周一到周五19点");
})

promise
    .then(r => console.log("第一个then",r))
    .catch(r => console.log("异常处理",r))
    .then(r => console.log("第二个then",r))

输出结果:

undefined 是.catch返回的新的promise的值

异常处理 每周一到周五19点
第二个then undefined


也可也设置新promise的返回值

const promise = new Promise((resolve, reject) => {
    reject("每周一到周五19点");
})

promise
    .then(r => "哈哈")
    .catch(r => {
        console.log("异常处理", r)
        return "嘻嘻"
    })
    .then(r => console.log("第二个then", r))

输出结果:

嘻嘻是catch中新的promise的返回值

异常处理 每周一到周五19点
第二个then 嘻嘻

注:对Promise进行链调用时,后边的方法(then和catch)读取的是上一步的执行结果,如果上一步的执行结果不是当前想要的结果,则跳过当前的方法


在promise中,后面的catch处理前面的错误

promise
    .then(r => "哈哈")
    .catch(r => {
        throw new Error("报个错玩")
        console.log("异常处理", r)
        return "嘻嘻"
    })
    .then(r => console.log("第二个then", r))
    .catch(r =>{
        console.log("出错了");
    })

注:只需要将catch写在最后即可


 类似资料: