从源码里分析 promise 奇特的特性。
1、promise 基本概念就不介绍了,es6,解决套套问题。。
2、本文主要记录下自己遇到的不懂的地方记录下,并没有全面去讲解。
3、外部一种实现promise的源码:https://github.com/ygm125/promise/blob/master/promise.js
先看个小例子的,
var promise = Promise.resolve(1);
promise.then(function(a){console.log(a,1);}).then(function(a){console.log(a,2)})
//在浏览器console执行的结果:
1 1
undefined 2
//promise库执行的结果:
1 1
1 2
显然,浏览器自己实现的 promise 和外部promise库的实现方案还是有细微差别的。但是这种差别不属于promise规范的范畴,你也可以实现自己更好用更多用途的。promise规范规定必须要异步的,浏览器实现的promise应该用的是浏览器内部的一些特性(不知道具体是什么),,,但是外部 promise 在 js 层面代码层面上怎么实现异步的呢,答案是:setTimeout()。。。
▲ promise的三种状态:pending、fullfilled,rejected。
promise构造函数的参数resolver,即是你自己的逻辑过程函数,该函数有两个参数,这两个参数会传与promise静态函数resolve和reject,你自己的逻辑过程函数逻辑(无论异步还是同步)写完后,记得在合适的地方调用这两个函数(这两个函数对应有自己的回调函数)即可,表示我的承诺已经给出来了。时机成熟时,调用处就是整个promise.then链条的发动处。
promise.resolve和reject动作对应的回调函数需要你自己注册进去的。
这个注册操作就是then函数了。
但是为什么可以把回调函数放到未来去注册?
理由是:异步(setTimeout异步或者浏览器自己的实现),确保了then()函数肯定在链条启动前就执行了!
then函数:
每then一次,都会返回一个新的promise对象。每次then的时候,首先判断调用者promise的状态:
这个then函数实现了一个特殊的地方见代码:68-77行,在于:你的fullfill回调有三种可能:
then里面有递归,还不同于一般的递归,不是可以很直观理解。这个递归决定了这个then可以有多种多样的then链条。
举例子:
function doubleUp(value) {
return value * 2;
}
function increment(value) {
return value + 1;
}
function output(value) {
console.log(value);// => (1 + 1) * 2
}
var promise = Promise.resolve(1);
promise
.then(increment)
.then(doubleUp)
.then(output)
.catch(function(error){
// promise chain中出现异常的时候会被调用
console.error(error);
});
再举例子:
function sleep(msecond){
return new Promise(function(a,b){
setTimeout(a,msecond);
});
}
//var promise = Promise.resolve(1);
var promise = sleep(1000);
promise.then(function(x){
console.log(x,1);
return Promise(function(a,b){
b(x);
});
}).then(function(x){console.log(x,2)})
.then(function(x){console.log(x,3)},function(x){console.log(x,4)})
还有更多各种嵌套的,都可以行的通。
▲ then链条如何保证顺序
1、promise1对象有了,显然是执行到setTimeout等待步骤了,状态是pending,timeout完成,立马就是fullfill状态并执行fullfill回调 函数func1
2、由于是异步,promise.then(func1)会在timeout完成前执行。
3、promise.then(func1)会新建promise2,即 new promies(resolver)。我们知道,在你的resovler代码里需要调用resovle函数才能使promise进入到setTimeout等待中。
4、链条连接点:func1里的新的promise2的resovler代码只有在promise状态为fullfill时才能执行。
5、也就是,只有promise1状态完成时,新的promise2才能进入setTimeout等待。
6、依次类推,,一环扣一环,,保证了链条有序执行。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。