-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第 13 题:Promise 构造函数是同步执行还是异步执行,那么 then 方法呢? #19
Comments
这里对上面的例子做一个扩展 const promise = new Promise((resolve, reject) => {
console.log(1);
resolve(5);
console.log(2);
}).then(val => {
console.log(val);
});
promise.then(() => {
console.log(3);
});
console.log(4);
setTimeout(function() {
console.log(6);
}); 执行结果: 124536 |
学习了 |
Promise new的时候会立即执行里面的代码 then是微任务 会在本次任务执行完的时候执行 setTimeout是宏任务 会在下次任务执行的时候执行 |
excutor执行器里面是同步执行的,then里面是异步操作 |
请问为什么3在val之前? |
3是在5后面打印出来的啊,第一轮事件循环的时候,microtask queue里面先添加的promise.resolve(5).then((val)=>{console.log(val)}),后添加的promise.then(() => { |
Promise必然是同步的。就then我补充一下: |
Promise 构造函数是同步执行,then 是异步执行。看一下 Promise 的实现就知道了。 |
看过 Event Loop 基础原理的就明白,Promise构造函数是同步执行,而 .then .catch .啥啥的是异步(还有process.nextTick等等,大家可以查), |
.then()当然是同步执行,只不过是.then的cb被放入了微任务队列,产生了异步执行 |
这个题和之前的第8题类似 |
then()到底是同步执行还是异步执行?为什么回答里有的说是同步有的说是异步 |
根据上面的回答,总结下应该是then函数本身是同步,then里面的cb是异步 |
只要好好理解下 Promise, 很多疑问会迎刃而解 |
请问在浏览器控制器中执行的时候,打印的3和6之间会有一个“随机数字”,它是怎么出现的,代表的什么呢? |
随机数字是 |
|
promise是微观任务,setTimeout是宏观任务,先执行微观任务,在执行宏观任务;微观任务里,先执行同步再执行异步 所以结果是 124536 |
promise构造函数肯定是同步执行的,new Promise和其他的什么new Map、new Set一样的都是同步执行,当执行resolve方法将promise状态更新为fulfilled,并返回一个promise对象,调用then就会将then中的回调放入微任务队列中,也就是说promise.then才是异步 |
严格来说 构造函数 then都是同步的, 只是then内部的这个参数回调函数需要看resolve执行时机 并且内部做了个定时器, 所以回调才是异步的 |
整体代码、setTimeout、setInterval、Promise构造函数是宏任务,promise的then方法是微任务 |
假如有这么一段代码 new Promise(resolve => {
resolve(1);
Promise.resolve().then(() => console.log(2));
Promise.resolve().then(() => console.log(5));
}).then(t => console.log(t)); 请问为什么输出结果是2,5,1呢? |
当然是异步啦,在执行resolve()之前会先将其他语句执行完的 |
Promise对象,就是将异步操作以同步操作的流程表达出来 |
我的天。then当然也是同步执行,then方法的参数callback函数才会在then等待状态变化的promise fulfill或者reject后起一个微任务把callback丢进去 |
这题还不如直接问Promise的原理或写法 |
更详细一点的说法是等到 promise变为 resolved状态的时候,then注册的回调函数才被放入到微任务队列中,等待调用执行 |
promise = new Promise((resolve, reject) => {
console.log(1);
setTimeout(() => {
resolve(5);
}, 10)
console.log(2);
}).then(val => {
console.log(val);
});
promise.then(() => {
console.log(3);
});
console.log(4);
setTimeout(function() {
console.log(6);
}); 补段代码 |
做戏做全套... 写一个更有助于理解 ps: 微任务以宏任务(setTimeout)替代 class PromiseA {
constructor(fn) {
this.status = 'pending';
this.value = null;
this.error = null;
this.resolveArr = [];
this.rejectArr = [];
let resolve = (value) => {
// 防止多次resolve
if (this.status !== 'pending') return;
setTimeout(()=>{
this.value = value;
this.status = 'fullfiled';
// 派发过往订阅
while(this.resolveArr.length) {
let tmp = this.resolveArr.shift();
tmp(value);
}
}, 0);
}
let reject = (err) => {
// 防止多次reject
if (this.status !== 'pending') return;
setTimeout(()=>{
this.status = 'rejected';
this.error = err;
// 派发过往订阅
while(this.rejectArr.length) {
let tmp = this.rejectArr.shift();
tmp(err);
}
}, 0);
}
fn(resolve, reject);
}
then(fun1, fun2) {
// 根据规范,如果then的参数不是function,则我们需要忽略它, 让链式调用继续往下执行
(typeof fun1 !== 'function') && (fun1 = value => value)
//
(typeof fun2 !== 'function') && (fun2 = error => {
throw(error);
})
return new PromiseA((resolve, reject)=>{
let resolveItem = (param) => {
try {
let tmp = fun1(param);
tmp instanceof PromiseA ? tmp.then(resolve, reject) : resolve(tmp);
} catch (e) {
reject(e);
}
}
let rejectItem = (err) => {
try {
let tmp = fun2(err);
tmp instanceof PromiseA ? tmp.then(resolve, reject) : resolve(tmp);
} catch (e) {
reject(e);
}
}
if (this.status == 'pending') {
this.resolveArr.push(resolveItem);
this.rejectArr.push(rejectItem);
} else if (this.status == 'fullfiled') {
resolveItem(this.value);
} else if (this.status == 'rejected') {
rejectItem(this.error);
}
});
}
catch(rejectFn) {
return this.then(null, rejectFn);
}
finally(fn) {
// 保证了fn执行在前.. 但是有点绕
return this.then((param)=>{
// 万一 fn reject了
return PromiseA.resolve(fn()).then(()=>param, ()=>param);
}, (err) =>{
// 万一 fn reject了
return PromiseA.resolve(fn()).then(()=>{
throw err;
}, ()=>{
throw err;
});
})
}
static resolve(param) {
if (param instanceof PromiseA) return param;
return new PromiseA((resolve)=>{
resolve(param);
})
}
static reject(param) {
if (param instanceof PromiseA) return param;
return new PromiseA((resolve, reject)=>{
reject(param);
})
}
static all(arr) {
return new PromiseA((resolve, reject)=>{
let i = 0;
let ret = [];
while(arr.length) {
let tmp = arr.shift();
tmp.then((param)=>{
ret[i] = param;
i++
if (i == arr.length) {
resolve(ret);
}
},(err) => {
reject(err);
})
}
});
}
static race(arr) {
// 只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。
return new PromiseA((resolve, reject) => {
arr.forEach((item)=>{
// 状态变化是单向的
item.then(resolve, reject);
})
})
}
// 允许reject X次 失败后Y秒继续触发
static retry(fn, x, y) {
return PromiseA((resolve, reject)=>{
let failTimes = 0;
// 也可以把历代err保存起来
// let errArr = [];
function cb () {
fn().then(resolve).catch((err)=>{
if (failTimes == x) {
reject(err);
return;
}
setTimeout(()=> {
cb();
}, y);
failTimes++;
});
}
cb();
})
}
static promisefy (cb) {
return (...arg)=>{
return new Promise((reoslve, reject)=>{
cb(...arg, reoslve);
})
}
}
} |
promise 的构造函数是同步执行的,then方法也是同步执行的,只不过 then 里面的回调函数是异步执行的。 |
⚠ 同志们,这道题绝对没有你们想象的这么简单,补充一个不错的文章中的摘录:
|
const promise = new Promise(async (resolve, reject) => { promise.then(() => { console.log(4); |
这种出现 await 的代码,你可以等价转化为: const promise = new Promise(async (resolve, reject) => {
console.log(1)
Promise.resolve(resolve()).then(() => {
console.log(2)
})
})
promise.then(() => {
console.log(3)
})
console.log(4); 也就是将 await 后面跟着的部分用一个 |
严格来说then方法 是同步执行的,then方法的参数(回调函数)是 异步执行的 |
如何体现呢?能举例说明吗? |
之所以then是异步是为了处理循环引用的问题。
判断then里面new的promise 跟successCallback执行后得到的p1是不是同一个promise。 |
【resolve对比await】这里虽然有resolve,但会打印同时先后打印1/2,如果是await,会先执行await后面的表达式,然后将其后的代码加入到微任务队列 |
promise是同步执行的,then也是同步的,只是then中的回调时异步执行的 |
可以看 promise的 实现 resolve 回调里的内容 会放入 微任务中 so 构造器里除了 resolve 之外的 都是 同步执行的(await resolve() 这种情况除外) |
这是来自QQ邮箱的假期自动回复邮件。
您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。
|
执行结果是:1243
promise构造函数是同步执行的,then方法是异步执行的
The text was updated successfully, but these errors were encountered: