浅谈:从回调地狱到Promise(三个实例方法,两个对象方法)

452 阅读2分钟

一.回调地狱的形成

如果一个请求b需要在拿到请求a中返回的参数后,才能正确发起请求,用传统的Ajax处理会有回调地狱的问题,及层层嵌套问题,代码不易读,后期亦不好维护。

function sayNum(name, callback) {
        setTimeout(() => {
            console.log(name);
            callback()
        }, 1000)
    }
    sayNum('one', function () {
        sayNum('two', function () {
            sayNum('three', function () {
                sayNum('four', function () {
                    console.log('结束了');
                })
            })
        })
    })
//打印结果 one two three four 结束了

二.Promise是如何解决回调地狱问题的

Promise是避免回调地狱的一个进步,通过.then( )的链式操作来触发多个异步任务,并且保证执行顺序,使得代码更易于阅读和维护。

怎么样,经过Promise化后,代码是不是看起来清晰多了。

function fn(num) {
        return new Promise(function (resolve, reject) {
            setTimeout(() => {
                console.log(num);
                resolve(num)
            }, 1000)
        })
    }
    
    var p1 = fn('one')
    p1.then((data) => {
            return fn('two')
        })
        .then((data) => {
            return fn('three')
        })
        .then((data) => {
            return fn('four')
        })
//  打印结果  one two three four

Promise的三个实例方法

resolve和reject两个回调函数分别隐射为Promise.then( )和Promise.catch( ),值得注意的是Promise还有第三个实例方法Promise.finally( ),无论成功与否都会触发

.then( )参数中的函数返回值:

  1. 返回promise实例对象: 返回的实例对象会调用下一个then
  2. 返回普通值: 如果.then返回的不是promise实例对象,而是一个普通值,那么这个then会返回一个默认的promise对象,从而保证能继续进行链式操作

Promise的两个对象方法:

Promise.all( ): 并发处理多个异步任务,所有任务都执行完成才能得到结果,并发处理的任务都是按照顺序执行的

        var p1 = fn('第一次')
        var p2 = fn('第二次')
        var p3 = fn('第三次')
        
        Promise.all([p1, p2, p3]).then((res) => {
            console.log(res);
        })
//  打印   ['第一次','第二次','第三次']

Promise.race( ):并发处理多个异步任务,只要有一个任务完成就能得到结果

        var p1 = fn('第一次')
        var p2 = fn('第二次')
        var p3 = fn('第三次')
        
        Promise.all([p1, p2, p3]).then((res) => {
            console.log(res);
        })
//  打印   第一次