Giter Club home page Giter Club logo

Comments (41)

kunish avatar kunish commented on May 17, 2024 116

这里对上面的例子做一个扩展

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.

KaiOrange avatar KaiOrange commented on May 17, 2024 49

Promise new的时候会立即执行里面的代码 then是微任务 会在本次任务执行完的时候执行 setTimeout是宏任务 会在下次任务执行的时候执行

from daily-interview-question.

Hunterang avatar Hunterang commented on May 17, 2024 30

.then()当然是同步执行,只不过是.then的cb被放入了微任务队列,产生了异步执行

from daily-interview-question.

sunas avatar sunas commented on May 17, 2024 7

Promise必然是同步的。就then我补充一下:
在ES6时代有了微异步的设定,then作为最典型代表,算是异步的一员。
在ES5时代,实现then的方式则要看构造函数里resolve(或reject)的用法了,如果resolve被同步使用,实质上resolve仍然是同步的。

from daily-interview-question.

pioneer26 avatar pioneer26 commented on May 17, 2024 5

excutor执行器里面是同步执行的,then里面是异步操作

from daily-interview-question.

thinkfish avatar thinkfish commented on May 17, 2024 4

then()到底是同步执行还是异步执行?为什么回答里有的说是同步有的说是异步

根据上面的回答,总结下应该是then函数本身是同步,then里面的cb是异步

from daily-interview-question.

zhukunpenglinyutong avatar zhukunpenglinyutong commented on May 17, 2024 3

看过 Event Loop 基础原理的就明白,Promise构造函数是同步执行,而 .then .catch .啥啥的是异步(还有process.nextTick等等,大家可以查),
而且放到了微队列中,async/await 中,await 前面的是同步,await 后面的是异步,写法上是这样,但是其实是 语法糖,最后还会转为 Promise.then的形式

from daily-interview-question.

fengmiaosen avatar fengmiaosen commented on May 17, 2024 2

.then()当然是同步执行,只不过是.then的cb被放入了微任务队列,产生了异步执行

更详细一点的说法是等到 promise变为 resolved状态的时候,then注册的回调函数才被放入到微任务队列中,等待调用执行

from daily-interview-question.

tjwyz avatar tjwyz commented on May 17, 2024 2

做戏做全套... 写一个更有助于理解

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.

wuzhong1030 avatar wuzhong1030 commented on May 17, 2024 1

Promise 构造函数是同步执行,then 是异步执行。看一下 Promise 的实现就知道了。

from daily-interview-question.

Chorer avatar Chorer commented on May 17, 2024 1

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.

LwDsmile avatar LwDsmile commented on May 17, 2024

学习了

from daily-interview-question.

yu910709 avatar yu910709 commented on May 17, 2024

这里对上面的例子做一个扩展

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.

cliYao avatar cliYao commented on May 17, 2024

这里对上面的例子做一个扩展

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.

iamwelk avatar iamwelk commented on May 17, 2024

这个题和之前的第8题类似

from daily-interview-question.

june38liu avatar june38liu commented on May 17, 2024

then()到底是同步执行还是异步执行?为什么回答里有的说是同步有的说是异步

from daily-interview-question.

dyj7 avatar dyj7 commented on May 17, 2024

这里对上面的例子做一个扩展

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
image

from daily-interview-question.

liwfd avatar liwfd commented on May 17, 2024

image

from daily-interview-question.

pekonchan avatar pekonchan commented on May 17, 2024

只要好好理解下 Promise, 很多疑问会迎刃而解

抓重点理解Promise

from daily-interview-question.

tiameg avatar tiameg commented on May 17, 2024

这里对上面的例子做一个扩展

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.

BajnHu avatar BajnHu commented on May 17, 2024

这里对上面的例子做一个扩展

常量 承诺 =   无极((决心,拒绝)=> {
   控制台。日志(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.

HuangHuanHuan avatar HuangHuanHuan commented on May 17, 2024

这里对上面的例子做一个扩展

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.

fqw123 avatar fqw123 commented on May 17, 2024

promise是微观任务,setTimeout是宏观任务,先执行微观任务,在执行宏观任务;微观任务里,先执行同步再执行异步 所以结果是 124536

from daily-interview-question.

Longgererer avatar Longgererer commented on May 17, 2024

promise构造函数肯定是同步执行的,new Promise和其他的什么new Map、new Set一样的都是同步执行,当执行resolve方法将promise状态更新为fulfilled,并返回一个promise对象,调用then就会将then中的回调放入微任务队列中,也就是说promise.then才是异步

from daily-interview-question.

huaipomen avatar huaipomen commented on May 17, 2024

严格来说 构造函数 then都是同步的, 只是then内部的这个参数回调函数需要看resolve执行时机 并且内部做了个定时器, 所以回调才是异步的

from daily-interview-question.

pigPEQ avatar pigPEQ commented on May 17, 2024

整体代码、setTimeout、setInterval、Promise构造函数是宏任务,promise的then方法是微任务

from daily-interview-question.

ftchan avatar ftchan commented on May 17, 2024

假如有这么一段代码

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.

Longgererer avatar Longgererer commented on May 17, 2024

应该

假如有这么一段代码

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.

tangdou369098655 avatar tangdou369098655 commented on May 17, 2024

Promise对象,就是将异步操作以同步操作的流程表达出来

from daily-interview-question.

lusq010 avatar lusq010 commented on May 17, 2024

我的天。then当然也是同步执行,then方法的参数callback函数才会在then等待状态变化的promise fulfill或者reject后起一个微任务把callback丢进去

from daily-interview-question.

ggzcg avatar ggzcg commented on May 17, 2024

这题还不如直接问Promise的原理或写法

from daily-interview-question.

slogeor avatar slogeor commented on May 17, 2024

.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.

MrLeihe avatar MrLeihe commented on May 17, 2024

promise 的构造函数是同步执行的,then方法也是同步执行的,只不过 then 里面的回调函数是异步执行的。

from daily-interview-question.

TenviLi avatar TenviLi commented on May 17, 2024

⚠ 同志们,这道题绝对没有你们想象的这么简单,补充一个不错的文章中的摘录:

在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队列。

—— https://segmentfault.com/a/1190000038985579

from daily-interview-question.

leeFengHuo avatar leeFengHuo commented on May 17, 2024

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.

gromy92 avatar gromy92 commented on May 17, 2024

严格来说then方法 是同步执行的,then方法的参数(回调函数)是 异步执行的

from daily-interview-question.

xuchao996 avatar xuchao996 commented on May 17, 2024

excutor执行器里面是同步执行的,then里面是异步操作

如何体现呢?能举例说明吗?

from daily-interview-question.

yumengbdw avatar yumengbdw commented on May 17, 2024

之所以then是异步是为了处理循环引用的问题。

const p1 = promise1.then(value => {
    return p1
})

判断then里面new的promise 跟successCallback执行后得到的p1是不是同一个promise。
但是then里面处理回调的时候new的promise还没有创建完成。

from daily-interview-question.

Yuweiai avatar Yuweiai commented on May 17, 2024
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.

WangYunFei1 avatar WangYunFei1 commented on May 17, 2024

promise是同步执行的,then也是同步的,只是then中的回调时异步执行的

from daily-interview-question.

Yangfan2016 avatar Yangfan2016 commented on May 17, 2024

可以看 promise的 实现

resolve 回调里的内容 会放入 微任务中
then 的回调只是一个list push 动作,
等 resolve 里的 微任务 执行完,就会 调用 then 里的 回调

so 构造器里除了 resolve 之外的 都是 同步执行的(await resolve() 这种情况除外)
then 里的回调是异步执行的

from daily-interview-question.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.