Promise实例代码分析

这篇文章主要介绍“Promise实例代码分析”,在日常操作中,相信很多人在Promise实例代码分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Promise实例代码分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

先来看一个问题

我们都知道 JavaScript 是单线程运行的,所以如果遇到一个数据需要过段时间才能获取到的情况,就会形成阻塞导致后面的代码也无法执行,而这相当致命,比如下面代码

function sum(a, b) {
    const begin = Date.now();
    while(Date.now() - begin < 10000) {

    }
    return a+b;
}

console.log(sum(1,2));
console.log("1");

中间的 while 语句经历了10秒的循环,最终才分别打印出了 3 和 1

然而我们希望的是允许3在10秒后再打印出来,但是1得先打印出来

这里我们就用到了setTimeout,修改代码如下

function sum(a, b) {
    setTimeout(() => {
        return a+b;
    },10000)
}

console.log(sum(1,2));
console.log("1");

运行一下可以看到1确实瞬间被打印出来了,但是本该打印3的位置是undefined

Promise实例代码分析  promise 第1张

原因在于此时的console.log同样没有等待setTimeout走完,无法接收到10秒后的数据

所以为了能够接收到这个10秒后的数据,我们可以采用回调函数的方式

function sum(a, b, callback) {

    setTimeout(() =>{
        callback(a+b);
    }, 10000)

}

sum(1,2,(result) => {
    console.log(result);
});
console.log("1");

传入了一个能够接收 a+b 为参数的回调函数 (result) => {console.log(result);}

所以在10秒后会执行这个回调函数,进行打印,结果如下

Promise实例代码分析  promise 第2张

这样我们就初步解决了这个问题,一个需要延时获取的数据在其他代码先执行后再被获取。

然而 Promise 还没出现,这就涉及了另一个需要改进的地方

回调地狱

这是个乍一听很唬人的称呼,实际上就是多层回调函数的嵌套导致的不利于阅读和调试的情况。

比如此时我们想要多次调用这个sum函数,要在得到1+2的结果后,再获得 1+2+3,1+2+3+4 这些结果

所以我们得在sum传入的回调函数里再多次调用sum进行嵌套,如下

sum(1,2,(result) => {
    sum(result, 3, (result) => {
        sum(result, 4, (result) => {
            console.log(result);
        })
    })
});

Promise实例代码分析  promise 第3张

这种类似金字塔的结构可读性差且不好调试,被称作回调地狱。

所以此时终于到了Promise出场的时候,它的出现解决了回调地狱的问题。

Promise 是什么

在使用Promise解决回调地狱的问题前,先来大致地了解一下什么是Promise。

目前我对它的判断是,Promise 是一个用于存取异步数据的对象。

首先来看一下空的 Promise 打印出来会是什么

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

Promise实例代码分析  promise 第4张

其中最关键的就是 PromiseState 和 PromiseResult 两个值,之后会详细展开,这里只要知道Promise中有着这两个属性即可。

接着来看一下 promise 存数据的过程,最关键的就是要知道有 resolve 和 reject,比如下面代码

const promise = new Promise((resolve, reject) => {
    const flag = true;
    if (flag) {
        resolve("resolve datas");
    } else {
        reject("reject data");
    }
})

此时flag为true,所以执行的是resolve的存储,得到的结果如下

Promise实例代码分析  promise 第5张

而当我们把flag改为false,执行reject的存储时,得到的结果如下

Promise实例代码分析  promise 第6张

现在是解释上面两个属性的时候了,

  • 当 promise 没有存储数据时,PromiseState 的值为 pending,PromiseResult的值为 undefined

  • 当 promise 使用 resolve 存储数据时,PromiseState 的值为 pending,PromiseResult的值为 相应存储值

  • 当 promise 使用 reject 存储数据时,PromiseState 的值为 rejected,PromiseResult的值为相应存储值

既然存有两种类型,读自然也要分两种

当我们读取promise中的数据时,我们需要使用如下的结构

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

如果数据存在resolve中,result会返回结果,如果存在reject中,reason会返回结果。

使用Promise解决回调地狱

在初步了解了Promise后,会发现目前Promise能做的事,使用回调函数也能完成。

所以最主要的还是Promise解决了回调地狱,比如之前的问题,可以写成这种形式

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

sum(1,2)
    .then(result => sum(result,3))
    .then(result => sum(result,4))
    .then(result => {
        console.log(result);
    })

promise 通过then方法进行读取后,是个新的Promise对象,比如我们可以打印一下

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

console.log(sum(1,2)
    .then(result => sum(result,3)))

Promise实例代码分析  promise 第7张

所以这也就给了我们能多次调用then方法的基础。

而这也就解决了回调地狱的问题。

到此,关于“Promise实例代码分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注蜗牛博客网站,小编会继续努力为大家带来更多实用的文章!

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:niceseo99@gmail.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

评论

有免费节点资源,我们会通知你!加入纸飞机订阅群

×
天气预报查看日历分享网页手机扫码留言评论Telegram