Promise基本使用(慕课Promise教程笔记)

很久没写博客了......看了很多关于Promise的文章,但是感觉也不是很理解,没办法去就看视频了。偶然发现慕课里有个关于Promise的视频,然后今天看了前两章,顺便整理了下笔记,记录下吧~

Promise

是什么?

  • 用于异步计算。

  • 可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果。

  • 可以在对象之间传递和操作Promise,帮助我们处理队列。

 

产生的原因

  • JavaScript包含大量的异步操作(AB工作的完成顺序,和交付他们时间顺序无关)

  • 异步操作的常见语法

    • 事件侦听和响应

    • 回调

  • 常见异步事件(浏览器中的JavaScript)

    • 异步操作以事件为主

    • 回调主要出现在Ajax和File API

  • Node.js是无阻塞高并发、依赖大量回调函数

 

异步回调的问题

  • 嵌套层次很深,容易陷入回调地狱,使得代码难以维护。

  • 无法正常使用return和throw。

  • 无法正常检索堆栈信息。

  • 多个回调之间难以建立联系。

ps:

  • 因为异步回调函数处于新的栈中,在此栈中无法获取之前的栈的信息,之前的栈也无法获取此栈中的错误,因此try和catch是无法生效的。

  • 因为无法判断异步执行顺序,只能在外层作用域声明大量的变量供内层作用域使用,导致这些变量有可能会被其他函数访问和修改,从而导致错误。

 

Promise详解

创建过程:

  1. 初始化Promise实例。

  2. 在实例中传入参数,该参数是一个函数(执行器)。

  3. 执行器拥有两个参数:resolve、reject。

  4. 成功调用resolve方法,失败调用reject方法。不同的方法执行完会改变Promise实例的状态。

  5. 执行then方法中对应的函数。

new Promise(
	/* 执行器 executor */
    function(resolve, reject) {
        // 一段耗时很长的异步操作
        
        resolve(); // 数据处理完成
        
        reject(); // 数据处理出错
    }
)
.then(function A() {
	// 成功,下一步
}, function B() {
	// 失败,做相应处理
});

理解:

  • Promise是一个代理对象,它和原先要进行的操作并无关系。

  • 它通过引入的一个回调,避免更多的回调。

  • Promise状态发生改变,就会触发.then()里的响应函数处理后续步骤。

  • Promise状态一经改变,不会再变。

  • Promise实例一经创建,执行器立即执行。

   

 

Promise的三个状态

  • pending【待定】初始状态 —— 实例化

  • fulfilled【实现】操作成功 —— 调用resolve

  • rejected【被否决】操作失败 —— 调用reject

 

简单范例

定时执行

console.log('here we go');
new Promise( resolve => {
    setTimeout( () => {
        resolve('hello');
    },2000);
})
    .then( value => {
    console.log(value + ' world');
})
​
//输出结果
// here we go
/* 
Promise {
    [[PromiseStatus]]: "resolved"
    [[PromiseValue]]: undefined
}
*/
// 两秒后
// hello world

执行顺序:先输出‘here we go’,接着执行定时器,两秒后将‘hello’传给.then()函数,输出‘hello, world'

 

两步执行(常用)

console.log('here we go');
new Promise( resolve => {
    setTimeout( () => {
        resolve('hello');
    }, 2000);
})
    .then ( value => {
        console.log( value );
        return new Promise( resolve => {
            setTimeout( () => {
                resolve('world');
            }, 2000);
        });
    })
    .then ( value => {
        console.log( value + ' world');
});
​
//输出结果
// here we go
/* 
Promise {
    [[PromiseStatus]]: "resolved"
    [[PromiseValue]]: undefined
}
*/
// 两秒后
// hello 
// 两秒后
// world world 

执行顺序:

先输出‘here we go',接着进入执行器,两秒后将'hello’传给第一个.then()函数;

第一个.then()函数输出‘hello',返回一个新的Promise;

新的Promise中开始执行器,两秒后将’world'传给‘第二个then函数;

第二个.then()函数输出’world world'。

 

对已完成的Promise执行.then()

console.log('start');
​
let promise = new Promise( resolve => {
    setTimeout( () => {
        console.log('the promise fulfilled');
        resolve('hello, world');
    }, 1000);
});
​
setTimeout( () => {
    promise.then( value => {
        console.log(value);
    })
}, 3000)
​
//输出结果
// start
/* 
Promise {
    [[PromiseStatus]]: "resolved"
    [[PromiseValue]]: undefined
}
*/
// the promise fulfilled
// 1秒后
// 两秒后
// hello, world

执行顺序:先输出‘start’,接着两个定时器同时执行,一秒后输出'the promise fulfilled',并将‘hello, world'传出;再过两秒,执行.then(),输出’hello, world'。

promise队列的重要特性

在任何地方生成了一个promise队列之后,我们可以把它作为一个变量进行床底,如果我们的操作是队列的状态,即先进先出的状态,就可以在后面追加任意多的.then(),不管之前的队列是完成还是没有完成,队列都会按照固定的顺序完成。(下个例子更形象)

 

在.then()函数里面不返回新的Promise(并不影响.then()的执行)

console.log('here we go');
new Promise( resolve => {
    setTimeout( () => {
        resolve('hello');
    }, 2000);
})
    .then( value => {
        console.log(value);
        console.log('everyone');
        (function() {
            return new Promise( resolve => {
                setTimeout( () => {
                    console.log('Mr.Laurence');
                    resolve('Merry Xmas');
                 }, 2000);
             });
        }());
        return false;
    })
    .then( value => {
        console.log( value + ' world');
})
​
//输出结果
// here we go
/* 
Promise {
    [[PromiseStatus]]: "resolved"
    [[PromiseValue]]: undefined
}
*/
// 两秒后
// hello
// everyone
// false world
// 两秒后
// Mr.Laurence

执行顺序:

输出‘here we go',进入Promise实例中,两秒后将’hello‘传给第一个.then();

第一个.then()输出’hello',接着输出‘everyone',接着执行立即执行函数。在此同时第一个.then()返回false,即将false传给第二个.then();

第二个.then()输出’false world';(如果注释掉return false,则输出'undefined world',可见返回结果不影响Promise继续往下执行)

在第一个.then()返回false后的两秒,输出'Mr.Lanrence'。

 

.then()

  • .then()接受两个函数作为参数,分别代表fulfilled和rejected

  • .then()返回一个新的Promise实例,所以它可以链式调用

  • 当前面的Promise状态改变时,.then()根据其最终状态,选择特定的状态响应函数执行

  • 状态响应函数可以返回新的Promise,或者其他值

  • 如果返回新的Promise,那么下一级.then()会在新Promise状态改变之后执行

  • 如果返回的是其他任何值,则会立即执行下一级.then()

console.log('start');
new Promise(resolve => {
    console.log('Step 1');
    setTimeout(() => {
        resolve(100);
    }, 1000);
})
    .then(value => {
        return new Promise(resolve => {
            console.log('Step 1-1');
            setTimeout(() => {
                resolve(110);
            }, 1000);
        })
    })
    .then(value => {
        console.log('Step 1-2');
        return value;
    })
    .then(value => {
        console.log('Step 1-3');
        return value;
    })
    .then(value => {
        console.log(value);
        console.log('Step 2');
})
​
// 输出
// start
// Step 1
// 一秒后
// Step 1-1
// Step 1-2
// Step 1-3
// 110
// Step 2

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章