想用Promise异步实现一个递归调用的接口,用来做简单AI的动作序列。发现一开始接触这个then的时候,不是很清楚,参考了网上的一些写法,改成自己的有问题,所以先静下心来研究一下这个调用的顺序问题
先看个例子,参考[1]
new Promise((resolve, reject) => {
console.log("promise")
resolve()
})
.then(() => { // 执行.then的时候生成一个promise是给最后一个.then的
console.log("then1")
new Promise((resolve, reject) => {
console.log("then1promise")
resolve()
})
.then(() => {// 执行这个.then的时候,生成的promise是下面一个then的
console.log("then1then1")
})
.then(() => {
console.log("then1then2")
})
})
.then(() => {
// 这个
console.log("then2")
})
结果:
promise
then1
then1promise
then1then1
then2
then1then2
问题:主要是疑惑then2在then1then1和then1then2之间
为了方便分析,列几个自己的理解,后面解释问题的时候方便。尤其是理论4和理论5
Promise是一个对象,他包含了
另外, resolve执行的时候会去检查Promise自己的队列,如果不是空的,会把回调函数体塞到nextTick队列中。 代码参考[4]
handlers.resolve = function (self, value) {
var result = tryCatch(getThen, value);
if (result.status === 'error') {
return handlers.reject(self, result.value);
}
var thenable = result.value;
if (thenable) {
safelyResolveThenable(self, thenable);
} else {
self.state = FULFILLED;
self.outcome = value;
var i = -1;
var len = self.queue.length;
while (++i < len) {
self.queue[i].callFulfilled(value);
}
}
return self;
};
参考[2],返回的Promise对象支持了链式调用
参考[2]返回值一节
(1)返回了一个值,那么 then 返回的 Promise 将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。
(2)没有返回任何值,那么 then 返回的 Promise 将会成为接受状态,并且该接受状态的回调函数的参数值为 undefined。
(3)抛出一个错误,那么 then 返回的 Promise 将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。
(4)返回一个已经是接受状态的 Promise,那么 then 返回的 Promise 也会成为接受状态,并且将那个 Promise 的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。
(5)返回一个已经是拒绝状态的 Promise,那么 then 返回的 Promise 也会成为拒绝状态,并且将那个 Promise 的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。
(6)返回一个未定状态(pending)的 Promise,那么 then 返回 Promise 的状态也是未定的,并且它的终态与那个 Promise 的终态相同;同时,它变为终态时调用的回调函数参数与那个 Promise 变为终态时的回调函数的参数是相同的。
参考[3],文章写的不错。大体讲明白了Promise和then的原理了。因为文章里面的截图不是很清楚,我还是去github上面翻源码出来看的舒服点,参考[4]
Promise.prototype.then = function (onFulfilled, onRejected) {
if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
typeof onRejected !== 'function' && this.state === REJECTED) {
return this;
}
var promise = new this.constructor(INTERNAL);
if (this.state !== PENDING) {
var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
unwrap(promise, resolver, this.outcome);
} else {
this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
}
return promise;
};
简单说明:
执行then函数的时候,如果Promise状态是Fulfilled的话,就执行unwrap那个逻辑,把then函数体通过nextTick放到一个全局的队列
执行then函数的时候,如果Promise是Pending状态,就执行 this.queue.push ,看到this就知道这个是放在Promise对象自己的一个队列里面
有了上面的这些理解,接下来分析一下一开始我不理解的打印结果。有些步骤简单明了,可能被我过了。当然,因为自己第一次去接触这个,所以步骤会写的比较繁琐一点~
如果例子中的new Promise改成,前面加一个return呢?
.then(() => { // 执行.then的时候生成一个promise是给最后一个.then的
console.log("then1")
new Promise((resolve, reject) => {
console.log("then1promise")
resolve()
})
// ===》改成
.then(() => { // 执行.then的时候生成一个promise是给最后一个.then的
console.log("then1")
// 就是这里的加了一个return
return new Promise((resolve, reject) => {
console.log("then1promise")
resolve()
})
根据[理论4],.then1函数体有了返回值,是一个Promise对象,而且是then1then2执行完返回的匿名Promise对象。所以只有等这个Promise对象resolve了之后,才会执行then2回调函数体的逻辑,所以’then2’最后才会打印。所以最终结果是:
promise
then1
then1promise
then1then1
then1then2
then2
Promise 想必大家十分熟悉,想想就那么几个 api,可是你真的了解 Promise 吗?本文根据 Promise 的一些知识点总结了十道题,看看你能做对几道。
本文写给有一定Promise使用经验的人,如果你还没有使用过Promise,这篇文章可能不适合你,Promise标准中仅指定了Promise对象的then方法的行为,其它一切我们常见的方法/函数都并没有指定.
Async/Await替代Promise的6个理由:Async/Await是近年来JavaScript添加的最革命性的的特性之一。它会让你发现Promise的语法有多糟糕,而且提供了一个直观的替代方法。
Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一,Promise 是一个构造函数, new Promise 返回一个 promise对象 接收一个excutor执行函数作为参数
这篇文章是考虑如何自己实现一个简单 Promise,用以理解 Promise。和原生 Promise的调用方法一样,支持链式调用,本文实现的方法只能用于参考Promise的原理,还有很多特性没有实现,比如 race,all 方法的实现。
在对数组进行一些遍历操作时,发现有些遍历方法对Promise的反馈并不是我们想要的结果。async/await为Promise的语法糖,文中会直接使用async/await替换Promise;map可以说是对Promise最友好的一个函数了,
最近在使用axios库时遇到了个问题,后端接口报了500错误,但前端并未捕获到。在axios整体配置的代码中,过滤http code时,调用了filter401()、filter500(),但是这里注意并未将两个filter函数的结果返回,也就是并未返回promise,这就是导致问题出现的原因
想必接触过Node的人都知道,Node是以异步(Async)回调著称的,其异步性提高了程序的执行效率,但同时也减少了程序的可读性。如果我们有几个异步操作,并且后一个操作需要前一个操作返回的数据才能执行
你可以在 .then 里面 return 一个 Promise,每次执行 .then 的时候都会自动创建一个新的 Promise,对调用者来说,Promise 的 resolved/rejected 状态是唯一的,Promise 构造函数不是解决方案,使用 Promise.resolve
Promise的一些用法在此不多赘述,本篇主要带领你手写一个Promise源码,学完你就会发现:Promise没有你想象中的那么难.本篇大概分为以下步骤:实现简单的同步Promise、增加异步功能、增加链式调用then、增加catch finally方法、增加all race 等方法、实现一个promise的延迟对象defer、最终测试
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!