Promise学习笔记(一)

前言

一开始学习前端的时候,很多技术都是学习其用法,实际上很少去了解其原理,因此在空闲时,去写一些笔记记录一下自己对一些常用技术的原理理解。

什么是Promise?

Promise 是ES6提供的一个对象,Promise对象代表了未来将要发生的事件,用来传递异步操作的消息;常用在网络请求中。

Promise对象的状态不受外界影响,它有三种状态

  · pending   进行中

  · fulfilled     已成功

  · rejected   已失败

Promise的状态只能由异步操作的结果决定。并且,Promise对象的状态既定,便不会再发生改变,且任何时候都能够得到其结果。Promise的状态改变通常只有 pending——fulfulled ||  pending——rejected。

Promise的优缺点

Promise对象可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。而且Promise对象提供了统一的接口,使得控制异步操作更加容易。

但是,Promise一旦新建就会立即执行,中途是无法取消的。其次,若不设置回调函数,Promise内部抛出的错误,是不会反应到外部(由于它内部不会受到外部的影响)。当Promise对象处于pending状态时,是无法得知目前进展到哪一个阶段。

 

Promise基础使用

使用一个东西的时候,我们常常需要了解这个东西内部提供了什么给我调用,所以先看一下Promise。

 

 通过打印可以看出来,Promise是一个构造函数,它本身有all、reject、resolve方法,原型上还有then、catch等方法。所以想要创建一个Promise,使用new关键字即可。

let pro = new Promise (function (resolve, reject) {

    setTimeout (function () {
        console.log('Promise执行完毕')
        resolve('返回数据,通知回调执行')
    }, 1000)
})

Promise的构造函数接收一个函数作为参数,函数传入了两个参数,分别为 resoleve 和 reject,前者代表了异步操作成功(pending—fulfilled)的回调函数,后者代表了异步操作失败(pending—rejected)的回调函数。

上面的代码,执行了一个异步操作,也就是定时器,在1秒后,输出“Promise执行完毕”,并且调用resolve方法。

实际上,当我们使用new关键字创建Promise对象时,被当做参数的函数传进去的时候已经执行了。所以我们使用Promise的时候,一般当做变量存放在一个函数中,在需要的时候再去运行这个函数。

function go () {
    let pro = new Promise (function (resolve, reject) {

        setTimeout (function () {
            console.log('Promise执行完毕')
            resolve('返回数据,通知回调执行')
        }, 1000)
    })

    return pro
}

那再看回来,为什么我们要把Promise包在函数中,还有就是resolve在这里面是什么作用。

上面的截图中,我们知道了Promise实际上是一个构造函数,可以调用then、catch方法。当我们将Promise包在函数中,我们可以这样使用

function go () {
    let pro = new Promise (function (resolve, reject) {

        setTimeout (function () {
            console.log('Promise执行完毕')
            resolve('返回数据,通知回调执行')
        }, 1000)
    })

    return pro
}

go().then(function(data){
    console.log('在这执行后续的操作,data是resolve传递的参数')
})

看了上面这段代码,就懂了,then里面的函数实际上差不多是我们平时使用的回调函数。这个时候,可能会有个疑惑,既然这样子的用法,跟我们平时调用方法再写回调函数没什么区别,为什么还要大费周折地去用Promise?那再往回调里去想,如果有多层回调,而且回调本身也是一个异步操作呢?如果按照传统的写法来处理,会进入回调地狱,后期维护成本会很大,维护难度高,而Promise可以在then中继续写Promise对象并返回,然后继续调用then来进行回调操作,可以避免上述问题。

看到这里,我们似乎忘记了什么,emmmm..... 就是reject。那我们看一下下面的代码,很容易就理解了,这里使用一段ajax请求来写。

function ajax(URL) {
    return new Promise(function (resolve, reject) {
        var req = new XMLHttpRequest(); 
        req.open('GET', URL, true);
        req.onload = function () {
            if (req.status === 200) { 
                resolve(req.responseText);
            } else {
                reject(new Error(req.statusText));
            } 
        };
        req.onerror = function () {
            reject(new Error(req.statusText));
        };
        req.send(); 
    });
}

var URL = "请求地址"; 
ajax(URL).then(
    function success(data){
        console.log('resolve') 
    },
    function fail(reason, data) {
        console.log('reject')
    }
)

请求成功时,我们会用resolve传递成功的返回值去进行回调操作,失败或者出现异常时,则使用reject传递参数。在代码中,可以看到,then方法中接收了两个函数作为参数,第一个为resolve的回调,第二个为reject的回调。

上述则是个人对于Promise基础使用的一些心得。

 

posted @ 2020-07-13 15:50  vegetbaleBrid  阅读(167)  评论(1编辑  收藏  举报