Comments (41)
这里对上面的例子做一个扩展
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
from daily-interview-question.
Promise new的时候会立即执行里面的代码 then是微任务 会在本次任务执行完的时候执行 setTimeout是宏任务 会在下次任务执行的时候执行
from daily-interview-question.
.then()当然是同步执行,只不过是.then的cb被放入了微任务队列,产生了异步执行
from daily-interview-question.
Promise必然是同步的。就then我补充一下:
在ES6时代有了微异步的设定,then作为最典型代表,算是异步的一员。
在ES5时代,实现then的方式则要看构造函数里resolve(或reject)的用法了,如果resolve被同步使用,实质上resolve仍然是同步的。
from daily-interview-question.
excutor执行器里面是同步执行的,then里面是异步操作
from daily-interview-question.
then()到底是同步执行还是异步执行?为什么回答里有的说是同步有的说是异步
根据上面的回答,总结下应该是then函数本身是同步,then里面的cb是异步
from daily-interview-question.
看过 Event Loop 基础原理的就明白,Promise构造函数是同步执行,而 .then .catch .啥啥的是异步(还有process.nextTick等等,大家可以查),
而且放到了微队列中,async/await 中,await 前面的是同步,await 后面的是异步,写法上是这样,但是其实是 语法糖,最后还会转为 Promise.then的形式
from daily-interview-question.
.then()当然是同步执行,只不过是.then的cb被放入了微任务队列,产生了异步执行
更详细一点的说法是等到 promise变为 resolved状态的时候,then注册的回调函数才被放入到微任务队列中,等待调用执行
from daily-interview-question.
做戏做全套... 写一个更有助于理解
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);
})
}
}
}
from daily-interview-question.
Promise 构造函数是同步执行,then 是异步执行。看一下 Promise 的实现就知道了。
from daily-interview-question.
const promise = new Promise(async (resolve, reject) => {
console.log(1)
await resolve()
console.log(2)
})promise.then(() => {
console.log(3)
})console.log(4);
碰到过这种扩展,想了解为什么2在3之前执行
这种出现 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 后面跟着的部分用一个 Promise.resolve()
包裹起来,然后剩余部分塞到一个 then 的回调函数里。这样再分析就简单了。
from daily-interview-question.
学习了
from daily-interview-question.
这里对上面的例子做一个扩展
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
请问为什么3在val之前?
from daily-interview-question.
这里对上面的例子做一个扩展
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
请问为什么3在val之前?
3是在5后面打印出来的啊,第一轮事件循环的时候,microtask queue里面先添加的promise.resolve(5).then((val)=>{console.log(val)}),后添加的promise.then(() => {
console.log(3);
});
from daily-interview-question.
这个题和之前的第8题类似
from daily-interview-question.
then()到底是同步执行还是异步执行?为什么回答里有的说是同步有的说是异步
from daily-interview-question.
这里对上面的例子做一个扩展
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); });
from daily-interview-question.
from daily-interview-question.
只要好好理解下 Promise, 很多疑问会迎刃而解
from daily-interview-question.
这里对上面的例子做一个扩展
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
请问在浏览器控制器中执行的时候,打印的3和6之间会有一个“随机数字”,它是怎么出现的,代表的什么呢?
from daily-interview-question.
这里对上面的例子做一个扩展
常量 承诺 = 新 无极((决心,拒绝)=> { 控制台。日志(1); 解析(5); 控制台。日志(2); })。然后(VAL => { 控制台。日志(VAL); }); 承诺。然后(()=> { 控制台。日志(3); }); 控制台。log(4); 的setTimeout(函数(){ 控制台。日志(6); });执行结果:124536
请问在浏览器控制器中执行的时候,打印的3和6之间会有一个“随机数字”,它是怎么出现的,代表的什么呢?
随机数字是seTimeout
方法的返回值
setTimeout()
方法的返回值是一个 **唯一的数值 **
如果你想要终止setTimeout()
方法的执行,那就必须使用 clearTimeout()
方法来终止,而使用这个方法的时候,系统必须知道你到底要终止的是哪一个setTimeout()
方法(因为你可能同时调用了好几个 setTimeout()
方法),这样clearTimeout()
方法就需要一个参数,这个参数就是setTimeout()
方法的返回值(数值),
用这个数值来唯一确定结束哪一个setTimeout()
方法。
from daily-interview-question.
这里对上面的例子做一个扩展
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
resolve(5)也能调用到下面这个then方法吗
promise.then(() => {
console.log(3);
});
from daily-interview-question.
promise是微观任务,setTimeout是宏观任务,先执行微观任务,在执行宏观任务;微观任务里,先执行同步再执行异步 所以结果是 124536
from daily-interview-question.
promise构造函数肯定是同步执行的,new Promise和其他的什么new Map、new Set一样的都是同步执行,当执行resolve方法将promise状态更新为fulfilled,并返回一个promise对象,调用then就会将then中的回调放入微任务队列中,也就是说promise.then才是异步
from daily-interview-question.
严格来说 构造函数 then都是同步的, 只是then内部的这个参数回调函数需要看resolve执行时机 并且内部做了个定时器, 所以回调才是异步的
from daily-interview-question.
整体代码、setTimeout、setInterval、Promise构造函数是宏任务,promise的then方法是微任务
from daily-interview-question.
假如有这么一段代码
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(1)
之后,不应该是优先注册了外部 .then
的回调吗?
还是说内部的 Promise
是同步执行的?
from daily-interview-question.
应该
假如有这么一段代码
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(1)
之后,不应该是优先注册了外部.then
的回调吗?
还是说内部的Promise
是同步执行的?
当然是异步啦,在执行resolve()之前会先将其他语句执行完的
from daily-interview-question.
Promise对象,就是将异步操作以同步操作的流程表达出来
from daily-interview-question.
我的天。then当然也是同步执行,then方法的参数callback函数才会在then等待状态变化的promise fulfill或者reject后起一个微任务把callback丢进去
from daily-interview-question.
这题还不如直接问Promise的原理或写法
from daily-interview-question.
.then()当然是同步执行,只不过是.then的cb被放入了微任务队列,产生了异步执行
更详细一点的说法是等到 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);
});
补段代码
from daily-interview-question.
promise 的构造函数是同步执行的,then方法也是同步执行的,只不过 then 里面的回调函数是异步执行的。
from daily-interview-question.
⚠ 同志们,这道题绝对没有你们想象的这么简单,补充一个不错的文章中的摘录:
在Promises/A+规范的Notes 3.1中提及了promise的then方法可以采用“宏任务(macro-task)”机制或者“微任务(micro-task)”机制来实现。所以开头提及的
promise
在不同浏览器的差异正源于此,有的浏览器将then
放入了macro-task
队列,有的放入了micro-task
队列。在jake
的博文Tasks, microtasks, queues and schedules中提及了一个讨论vague mailing list discussions,一个普遍的共识是promises
属于microtasks
队列。
from daily-interview-question.
const promise = new Promise(async (resolve, reject) => {
console.log(1)
await resolve()
console.log(2)
})
promise.then(() => {
console.log(3)
})
console.log(4);
碰到过这种扩展,想了解为什么2在3之前执行
from daily-interview-question.
严格来说then方法 是同步执行的,then方法的参数(回调函数)是 异步执行的
from daily-interview-question.
excutor执行器里面是同步执行的,then里面是异步操作
如何体现呢?能举例说明吗?
from daily-interview-question.
之所以then是异步是为了处理循环引用的问题。
const p1 = promise1.then(value => {
return p1
})
判断then里面new的promise 跟successCallback执行后得到的p1是不是同一个promise。
但是then里面处理回调的时候new的promise还没有创建完成。
from daily-interview-question.
const promise = new Promise((resolve, reject) => { console.log(1) resolve() console.log(2) }) promise.then(() => { console.log(3) }) console.log(4)
执行结果是:1243 promise构造函数是同步执行的,then方法是异步执行的
【resolve对比await】这里虽然有resolve,但会打印同时先后打印1/2,如果是await,会先执行await后面的表达式,然后将其后的代码加入到微任务队列
from daily-interview-question.
promise是同步执行的,then也是同步的,只是then中的回调时异步执行的
from daily-interview-question.
可以看 promise的 实现
resolve 回调里的内容 会放入 微任务中
then 的回调只是一个list push 动作,
等 resolve 里的 微任务 执行完,就会 调用 then 里的 回调
so 构造器里除了 resolve 之外的 都是 同步执行的(await resolve() 这种情况除外)
then 里的回调是异步执行的
from daily-interview-question.
Related Issues (20)
- ``` javascript HOT 2
- 反转数字字符串 HOT 2
- es11
- 实现
- [...new Set(arr.toString().split(',').sort((a,b) => a-b ))].map(item => Number(item))
- let nums1 = [3,3,2] let nums2 = [1,2,3,3,2,2,4444] function res (nums1,nums2){ let a = [] for (const item of nums1) { for (const i in nums2) { if(item==nums2[i]){ a.push(nums2[i]) nums2.splice(i,1) break } } }; return a } console.log(res(nums1,nums2))
- splice插入
- 自己回答一波,若有错误请各位指出,互相学习!谢谢 ~
- 递归
- 第226题:TS 中逆变和协变如何理解
- objmap
- 通过协程来实现
- 这代码写的...
- 第 161 题:用最精炼的代码实现数组非零非负最小值 index HOT 2
- No description provided.
- > 就我的使用来说(Vue)key的作用是为了在数据变化时强制更新组件,以避免“原地复用”带来的副作用,官方文档也说明了**不带key性能更好**,见:[List Rendering - key](https://cn.vuejs.org/v2/guide/list.html#key)
- 解释原因
- an
- 同步/异步 > 微任务>宏任务
- Object.prototype,map
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from daily-interview-question.