资讯专栏INFORMATION COLUMN

关于Promise

stdying / 1013人阅读

摘要:是一种异步编程的解决方案相比传统回调函数更合理立即执行性立即执行返回成功后执行控制台输出立即执行后执行返回成功对象表示未来发生的事件在创建时作为参数传入的函数是会被立即执行的只是其中执行的代码可以是异步代码有些人会认为当对象调用方法时接受的

Promise是一种异步编程的解决方案,相比传统回调函数更合理.

1.Promise立即执行性

let p = new Promise((resolve, reject) => {
    console.log("立即执行!");
    resolve("返回成功!")
});

console.log("promise后执行!");

p.then(value => {
    console.log(value)
});

控制台输出:

"立即执行!"
"promise后执行!"
"返回成功!"

Promise对象表示未来发生的事件,在创建promise时,作为promise参数传入的函数是会被立即执行的,只是其中执行的代码可以是异步代码.有些人会认为,当promise对象调用then方法时,promise接受的函数才会执行,这是错误的.所以,代码中立即执行!先于promise后执行!输出.

2.Promise的三种状态.

let p1 = new Promise((reslove, reject) => {
    reslove(1);
});
let p2 = new Promise((reslove, reject) => {
    setTimeout(() => {
        reslove(2);
    }, 500);
});
let p3 = new Promise((reslove, reject) => {
    setTimeout(() => {
        reject(3);
    }, 500);
});

console.log(p1);
console.log(p2);
console.log(p3);
setTimeout(() => {
    console.log(p2);
}, 1000);
setTimeout(() => {
    console.log(p3);
}, 1000);

p1.then(value => {
    console.log(value);
});
p2.then(value => {
    console.log(value);
});
p3.catch(err => {
    console.log(err);
});

控制台输出:

Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 1}
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
1
2
3
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 2}
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: 3}

Promise内部实现是一个状态机.Promise有三种状态: pending,resolved,rejected.当Promise刚创建完成时,处于pending状态;当Promise中的函数参数执行了resolve后,Promise由pending状态变成resloved状态;如果Promise的函数参数中执行的是reject方法,那么Promise会有pending状态变成rejected状态.

3.Promise状态不可逆性.

let p1 = new Promise((reslove, reject) => {
    reslove("成功1!");
    reslove("成功2!");
});
let p2 = new Promise((reslove, reject) => {
    reslove("成功!");
    reject("失败!");
});

p1.then(value => {
    console.log(value);
});
p2.then(value => {
    console.log(value);
});

控制台输出:

"成功1!"
"成功!"

Promise的状态一旦变成resolved或rejected时,Promise的状态和值就固定下来了,无论后续再怎么调用reslove或是reject方法,都不能改变它的状态和值.所以,p1中reslove("成功2!")并不能将p1的值更改为成功2!,p2中reject("失败!")也不能将p2的状态由resolved改变为rejected.

4.链式调用.

let p = new Promise((resolve, reject) => {
    resolve(1);
});

p.then(value => {
    console.log(value);
    return value * 2;
}).then(value => {
    console.log(value);
}).then(value => {
    console.log(value);
    return Promise.resolve("resolve");
}).then(value => {
    console.log(value);
    return Promise.reject("reject");
}).then(value => {
    console.log(`resolve: ${value}`);
}, err => {
    console.log(`reject: ${err}`);
})

控制台输出:

1
2
undefined
"resolve"
"reject: reject"

Promise对象的then方法返回一个新的Promise对象,所以可以通过链式调用then方法.then方法接受两个函数作为参数,第一个参数是Promise执行成功时的回调,第二个参数是Promise执行失败时的回调.两个函数只会有一个被调用,函数返回值将用作创建then返回的Promise对象.这两个参数的返回值可以是下面三种情况的一种:

①:return一个同步的值,或者undefined(当没有返回一个有效值时,默认返回undefined),then方法将返回一个resloved状态的Promise对象,Promise对象的值就是这个返回值.
②:return另一个Promise,then方法将根据这个Promise的状态和值创建一个新的Promise对象返回.
③:throw一个同步异常,then方法将返回一个rejected状态的Promise,值是该异常.

根据以上分析,代码中的第一个then会返回一个值为2(1 * 2),状态为resolved的Promise对象,于第二个then输出的值为2.第二个then中没有返回值,因此将返回默认的undefined,于是在第三个then中输出的undefined.第三个then和第四个then中分别返回一个状态是resloved的Promise和一个状态是rejected的Promise,依次由第四个then中的成功回调函数和第五个then中的失败回调函数处理.
5.Promise then()回调异步性.

let p = new Promise((resolve, reject) => {
    resolve("成功!");
});

p.then(value => {
    console.log(value);
});

console.log("谁先执行?")

控制台输出:

"谁先执行?"
"成功!"

Promise接受的函数参数是同步执行的,但是then方法中的回调函数则是异步的,因此,成功!会在后面输出.
6.Promise中的异常.

let p1 = new Promise((resolve, reject) => {
    foo.bar();
    resolve(1);
});

p1.then(value => {
    console.log(`p1 then value: ${value}`);
}, err => {
    console.log(`p1 then err: ${err}`);
}).then(value => {
    console.log(`p1 then then value: ${value}`);
}, err => {
    console.log(`p1 then then err: ${err}`);
});

let p2 = new Promise((resolve, reject) => {
    resolve(2);
});

p2.then(value => {
    console.log(`p2 then value: ${value}`);
    foo.bar();
}, err => {
    console.log(`p2 then err: ${err}`);
}).then(value => {
    console.log(`p2 then then value: ${value}`);
}, err => {
    console.log(`p2 then then err: ${err}`);
    return 1;
}).then(value => {
    console.log(`p2 then then then value: ${value}`);
}, err => {
    console.log(`p2 then then then err: ${err}`);
});

控制台输出:

p1 then err: ReferenceError: foo is not defined
p2 then value: 2
p1 then then value: undefined
p2 then then err: ReferenceError: foo is not defined
p2 then then then value: 1

Promise中的异常由then参数中的第二个回调函数(Promise执行失败的回调)处理,异常信息将作为Promise的值.异常一旦得到处理,then返回后续的Promise对象将恢复正常,并会被Promise执行成功的回调函数处理.另外,需要注意p1,p2多级then的回调函数是交替执行的,这正是由Promise then回调的异步性决定的.

7.Promise.reslove().

let p1 = Promise.resolve(1);
let p2 = Promise.resolve(p1);
let p3 = new Promise((resolve, reject) => {
    resolve(1);
});
let p4 = new Promise((resolve, reject) => {
    resolve(p1);
});

console.log(p1 === p2);
console.log(p1 === p3);
console.log(p1 === p4);
console.log(p3 === p4);

p4.then(value => {
    console.log(`p4=${value}`)
});
p2.then(value => {
    console.log(`p2=${value}`)
});
p1.then(value => {
    console.log(`p1=${value}`)
});

控制台输出:

true
false
false
false
p2=1
p1=1
p4=1

Promise.resolve(...) 可以接受一个值或者是一个Promise对象作为参数.当参数是普通值时,它返回一个resolved状态的Promise对象,对象的值就是这个参数;当参数是一个Promise对象时,它直接返回这个Promise参数.所以p1===p2.但通过new创建的Promise对象都是一个新的对象,所以后面三个比较结果都是false.另外,为什么p4的then最先调用,但是在控制台上是最后输出结果的呢?因为p4中resolve接受的参数是一个Promise对象p1,reslove会对p1进行解析,获取p1的状态和值,但是这个过程是异步的.

8.resolve v reject.

let p1 = new Promise((resolve, reject) => {
    resolve(Promise.resolve("resolve"));
});
let p2 = new Promise((resolve, reject) => {
    resolve(Promise.reject("reject"));
});
let p3 = new Promise((resolve, reject) => {
    reject(Promise.resolve("resolve"));
});

p1.then(value => {
    console.log(`p1 fulfilled: ${value}`);
}, err => {
    console.log(`p1 rejected: ${err}`);
});
p2.then(value => {
    console.log(`p2 fulfilled: ${value}`);
}, err => {
    console.log(`p2 rejected: ${err}`);
});
p3.then(value => {
    console.log(`p3 fulfilled: ${value}`);
}, err => {
    console.log(`p3 rejected: ${err}`);
});

控制台输出:

p3 rejected: [object Promise]
p1 fulfilled: resolve
p2 rejected: reject

Promise回调函数中的第一个参数resolve,会对Promise执行解析,即resolve的参数是Promise对象时,resolve会解析获取这个Promise对象的状态和值,但这个过程是异步的.p1解析后,获取到Promise对象的状态是resolved,因此第一个回调被执行也就是获取value的回调;p2解析后,获取到Promise对象的状态rejected,因此rejected回调执行.但Promise回调函数中的第二个参数reject不具备解析能力,reject的参数会直接传递给then方法中的rejected回调,因此,即使p3 reject接受了一个resolved状态的Promise,then方法中调用的依然是rejected,并且参数就是reject接受到的Promise对象.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84427.html

相关文章

  • 关于promise的小结

    摘要:则是把类似的异步处理对象和处理规则进行规范化,并按照采用统一的接口来编写,而采取规定方法之外的写法都会出错。这个对象有一个方法,指定回调函数,用于在异步操作执行完后执行回调函数处理。到目前为止,已经学习了创建对象和用,方法来注册回调函数。 Promise 本文从js的异步处理出发,引入Promise的概念,并且介绍Promise对象以及其API方法。 js里的异步处理 可以参考这篇文章...

    Tony_Zby 评论0 收藏0
  • 关于es6--promise

    摘要:就算改变已经发生了,你再对对象添加回调函数,也会立即得到这个结果。有了对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。但是在这里,会得到这样的结果关于是用于指定发生错误时的回调函数。 看了很多关于promise的文章,此篇文章做以总结。由于Javascript是一种单线程的语言,所有的代码必须按照所谓的自上而下的顺序来执行。本特性带来的问题就是,一些将来的、未...

    tommego 评论0 收藏0
  • 关于 Promise 的 9 个提示

    摘要:关于的个提示正如同事所说的那样,在工作中表现优异。这篇文章会给你一些如何改善与之间关系的建议。但是对于一个初学者来说,可能就不会了。在中不论你使用或者都会创建一个新的。这个是刚刚链式调用的和刚刚加上的的组合。 关于 Promise 的 9 个提示 正如同事所说的那样,Promise 在工作中表现优异。 showImg(https://segmentfault.com/img/remot...

    Leo_chen 评论0 收藏0
  • 关于promise的学习和拓展

    摘要:秒钟后调用函数观察上述代码执行,在的控制台输出可以看到就是典型的异步操作统一执行逻辑,不关心如何处理结果,然后,根据结果是成功还是失败,在将来的某个时候调用函数或函数。 Promise的学习和拓展 以前开发的时候偶尔会在请求中,或者其他场景中用到promise,只知道它是什么(链式调用,用于请求的后返回值得操作之类的),大概怎么用,却没有深入了解。 起因:(在参考了廖雪峰的prom...

    mayaohua 评论0 收藏0
  • 关于 ES6 中 Promise 的面试题

    摘要:执行,输出,宏任务执行结束。到此为止,第一轮事件循环结束。参考入门阮一峰系列之我们来聊聊一道关于应用的面试题阿里前端测试题关于中函数的理解与应用这一次,彻底弄懂执行机制一个面试题原生的所有方法介绍附一道应用场景题目异步流程控制 说明 最近在复习 Promise 的知识,所以就做了一些题,这里挑出几道题,大家一起看看吧。 题目一 const promise = new Promise((...

    dreambei 评论0 收藏0
  • 关于Promise

    摘要:反之,操作失败,对象由状态转换为状态,此时回调函数会执行方法。这里需要注意的是,虽然在之后便执行了方法,但是并不是意味着往后的对象不执行了,其他的还是对象还是要执行的,只是不会再调用函数。 在 掘金上看见一篇写promise的文章,感觉作者写的很棒,文章链接在这:八段代码彻底掌握 Promise 。看完之后感觉学到了很多,所以又重新把JavaScript Promise迷你书(中文版)...

    546669204 评论0 收藏0

发表评论

0条评论

stdying

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<