精华内容
下载资源
问答
  • promisesetTimeout执行顺序的问题

    万次阅读 2018-04-23 18:48:41
    前言 ...promise为es6引进的语言标准,为异步编程的一种解决方案;...阅读此文的前提是了解promise的基本用法和特性,比如他自执行特性、状态不...setTimeout(function(){console.log(1)},0); new Promise(fu...

    欢迎访问我的个人博客:http://www.xiaolongwu.cn

    前言

    promise为es6引进的语言标准,为异步编程的一种解决方案;

    阅读此文的前提是了解浏览器event loop的机制,还有promise的基本用法和特性,比如他自执行特性、状态不可逆特性等

    抛出问题

    且看下面代码和问题

    setTimeout(function(){console.log(1)},0);
    new Promise(function(resolve){
        console.log(2)
        for( var i=0 ; i<10000 ; i++ ){
            i==9999 && resolve()
        }
        console.log(3)
    }).then(function(){
        console.log(4)
    });
    console.log(5);
    // 这的问题是,为什么答案是 2 3 5 4 1
    // 而不是 2 3 5 1 4
    

    既然promise.then和setTimeout都是异步的,那么在事件循环队列中 promise.then的事件应该排在setTimeout后面,那为什么promise.then却在setTimeout前面被打印了出来?

    重要概念

    event loop 的概念

    • Javascript是单线程的,所有的同步任务都会在主线程中执行。

    • 当主线程中的任务,都执行完之后,系统会 “依次” 读取任务队列里的事件。与之相对应的异步任务进入主线程,开始执行。

    • 异步任务之间,会存在差异,所以它们执行的优先级也会有区别。大致分为 微任务(micro task,如:Promise、MutaionObserver等)和宏任务(macro task,如:setTimeout、setInterval、I/O等)。

    • Promise 执行器中的代码会被同步调用,但是回调是基于微任务的。

    • 宏任务的优先级高于微任务

    • 每一个宏任务执行完毕都必须将当前的微任务队列清空

    • 第一个 script 标签的代码是第一个宏任务

    • 主线程会不断重复上面的步骤,直到执行完所有任务。

    我的理解

    我们来捋一遍代码的执行过程,

    所有的代码都写在script标签中,所以读取所有代码是第一个宏任务,我们开始执行第一个宏任务。

    我们首先遇到setTimeout,他是第二个宏任务,将它扔进宏任务事件队列里先排队。

    下来我们遇到promise,promise执行器里的代码会被同步调用,所以我们依次打印出2和3。

    下来遇到promise的回调,他是一个微任务,将它扔进微任务事件对列中。

    下来我们接着打印出5,然后执行微任务并且打印出4.

    我们第一个宏任务执行完毕,执行下一个宏任务,打印出1,到此,所有任务都执行完毕。

    所以我们最后的结果为2 3 5 4 1。

    结束

    github资源地址:js基础进阶–promise和setTimeout执行顺序的问题

    csdn博客地址:https://blog.csdn.net/wxl1555

    如果您对我的博客内容有疑惑或质疑的地方,请在下方评论区留言,或邮件给我,共同学习进步。

    邮箱:wuxiaolong802@163.com

    展开全文
  • JavaScript中PromisesetTimeout的区别

    千次阅读 2018-03-12 20:16:29
    最近在看vue源码,发现vue中的nextTick异步更新dom操作是先判断是否支持Promise,如果不支持就判断是否支持MutationObserval,如果也不支持的话,最后才是setTimeout。/** * Defer a task to execute it ...

        最近在看vue源码,发现vue中的nextTick异步更新dom操作是先判断是否支持Promise,如果不支持就判断是否支持MutationObserval,如果也不支持的话,最后才是setTimeout。

    /**
     * Defer a task to execute it asynchronously.
     */
    var nextTick = (function () {
      var callbacks = [];
      var pending = false;
      var timerFunc;
    
      function nextTickHandler () {
        pending = false;
        var copies = callbacks.slice(0);
        callbacks.length = 0;
        for (var i = 0; i < copies.length; i++) {
          copies[i]();
        }
      }
    
      // the nextTick behavior leverages the microtask queue, which can be accessed
      // via either native Promise.then or MutationObserver.
      // MutationObserver has wider support, however it is seriously bugged in
      // UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It
      // completely stops working after triggering a few times... so, if native
      // Promise is available, we will use it:
      /* istanbul ignore if */
      if (typeof Promise !== 'undefined' && isNative(Promise)) {
        var p = Promise.resolve();
        var logError = function (err) { console.error(err); };
        timerFunc = function () {
          p.then(nextTickHandler).catch(logError);
          // in problematic UIWebViews, Promise.then doesn't completely break, but
          // it can get stuck in a weird state where callbacks are pushed into the
          // microtask queue but the queue isn't being flushed, until the browser
          // needs to do some other work, e.g. handle a timer. Therefore we can
          // "force" the microtask queue to be flushed by adding an empty timer.
          if (isIOS) { setTimeout(noop); }
        };
      } else if (!isIE && typeof MutationObserver !== 'undefined' && (
        isNative(MutationObserver) ||
        // PhantomJS and iOS 7.x
        MutationObserver.toString() === '[object MutationObserverConstructor]'
      )) {
        // use MutationObserver where native Promise is not available,
        // e.g. PhantomJS, iOS7, Android 4.4
        var counter = 1;
        var observer = new MutationObserver(nextTickHandler);
        var textNode = document.createTextNode(String(counter));
        observer.observe(textNode, {
          characterData: true
        });
        timerFunc = function () {
          counter = (counter + 1) % 2;
          textNode.data = String(counter);
        };
      } else {
        // fallback to setTimeout
        /* istanbul ignore next */
        timerFunc = function () {
          setTimeout(nextTickHandler, 0);
        };
      }

        当时觉得很奇怪,为何要这样做区分,为何要优先使用Promise,而不是优先使用setTimeout。后来才知道原来牵扯到task和micro task。

       我们先看如下一个demo,看输出结果是什么?

    console.log(1);
    	
    setTimeout(()=>{
    	console.log(2)
    },100)
    	
    Promise.resolve().then(()=>{
    	console.log(3);
    })
    	
    console.log(4);

        结果是1 4 3 2。可能很多人会奇怪为何不是1 4 2 3!

        其实这里Promise是一个micro task,我们的主线程是一个task。micro task会在task后面执行,然后才会接着执行下一个task。而setTimeout的返回函数是一个新的task,所以这里Promise的执行会先于新task执行。根据HTML标准,一个task执行完后,UI会重渲染,所以micro task更新完数据后再渲染dom的操作要比setTimout的性能要好。如果使用setTimeout的话,会有两次ui重渲染。task和micro task的详情可以参考https://www.cnblogs.com/dong-xu/p/7000139.html

    展开全文
  • 宏任务一般包括:整体代码script,setTimeout,setInterval。 微任务:Promise,process.nextTick先执行 **先同步再取出第一-个宏任务执行所有的相关微任务总会在下个宏任务之 前全部执行完毕 如果遇见就 先微...

    事件循环:

     

    宏任务一般包括:整体代码script,setTimeout,setInterval。

     

    微任务:Promise,process.nextTick先执行

    **先同步再取出第一-个宏任务执行所有的相关微任务总会在下个宏任务之 前全部执行完毕 如果遇见就

    先微后宏**

     

     

    let promise=new Promise(()=>{
        console.log('Promise')
        resolve()
    })
    
    setTimeout(()=>{
        console.log(1)
    },0)
    
    setTimeout(()=>{
        console.log(2)
    })
    
    let promise2=new Promise(()=>{
        console.log('Pomise2')
        resolve()
    })
    
    promise2.then(()=>{
        console.log('resloved2')
    })
    
    promise.then(()=>{
        console.log('resolved')
    })

    new Promise 声明后会立即执行 或者 Promise.reslove()也会立即执行 Promise一旦被定义,就会立即执行

    promise.then(()=>{

    这里里面属于微任务

    })

     

    Promise优先于setTimeout宏任务。所以 ,setTimeout回调会在最后执行。

    Promise一旦被定义,就会立即执行。

    Promise的reject和resolve是异步执行的回调。所以,resolve()会被放到回调队列中,在主函数执行完和setTimeout前调用。

     

     

    async 告诉程序这是一个异步操作,await 是一个操作符,即 await 后面是一个表达式

    await 执行完后,会让出线程。async标记的函数会返回一个Promise对象

    async ,会立即执行Promise对象,造成同步的函数,按顺序执行

    await 返回一个Promise.reslove(),会立即执行,并返回结果,不推入微任务内

    这两个搭配执行后,就会返回resolve()状态

    展开全文
  • 题目描述:写出执行结果,并解释原因 async function async1() { console.log('async1 start'); await async2(); console.log('async1 end'); } async function async2() { ...setTimeout(()=>{ console.log

    题目描述:写出执行结果,并解释原因

    async function async1() {
        console.log('async1 start');
        await async2();
        console.log('async1 end');
    }
     
    async function async2() {
        console.log('async2');
    }
     
    console.log('script start');
     
    setTimeout(()=>{
        console.log('setTimeout');
    },0)
     
    async1();
     
    new Promise((resolve)=>{
        console.log('promise1');
        resolve();
    }).then(()=>{
        console.log('promise2');
    });
     
    console.log('script end');
    

    答案:

    script start
    async1 start
    async2
    promise1
    script end
    async1 end
    promise2
    setTimeout
    

    知识点:
    考察的是事件循环和回调队列。注意以下几点:

    1. Promise 优先于 setTimeout 宏任务,所以 setTimeout 回调会最后执行 Promise 一旦被定义就会立即执行
    2. Promise 的 resolve 和 reject 是异步执行的回调。所以 resolve() 会被放到回调队列中,在主函数执行完和
    3. setTimeout 之前调用 await 执行完后,会让出线程。async 标记的函数会返回一个 Promise 对象

    解析:
    首先,事件循环从宏任务(macrostack)队列开始,这个时候,宏任务队列中,只有一个 script (整体代码)任务。从宏任务队列中取出一个任务来执行。
    首先执行 console.log(‘script start’),输出 ‘script start’
    遇到 setTimeout 把 console.log(‘setTimeout’) 放到 macrotask 队列中
    执行 aync1() 输出 ‘async1 start’ 和 ‘async2’ ,把 console.log(‘async1 end’) 放到 micro 队列中
    执行到 promise ,输出 ‘promise1’ ,把 console.log(‘promise2’) 放到 micro 队列中
    执行 console.log(‘script end’),输出 ‘script end’
    macrotask 执行完成会执行 microtask ,把 microtask quene 里面的 microtask 全部拿出来一次性执行完,所以会输出 ‘async1 end’ 和 ‘promise2’
    开始新一轮的事件循环,去除执行一个 macrotask 执行,所以会输出 ‘setTimeout’

    转载:https://blog.csdn.net/MFWSCQ/article/details/105109727

    展开全文
  • 宏任务 :setTimeout、setInterval 宏任务 :promise nixtTick EvenT Loop JS得事件循环机制 js得执行模式有点像排队得模式,执行完一个执行下一个,这时候有一些任务需要很长时间才能完成,这时候就有了一个异步...
  • emmmm…遇到一题目,promise为什么比setTimeout先执行,查阅了很多文档基本都是说了事件循环的大概的理念,都没有根据事件循环的概念深入解释promisesetTimeout先执行的原因。实在不太喜欢半吊子的解释,也有可能...
  • setTimeout 属于宏任务(MacroTask), Promise 属于微任务(MicroTask),二者并不在一个异步队列中。 无论是宏任务还是微任务,都是异步任务。在 JavaScript 中的异步是靠事件循环来实现的,拿大家最常见的 ...
  • async function async1() { console.log(“async1 start”); await async2(); console.log(“async1 end”); } async function async2() { console.log(‘async2’);...console.log(“script ...setTimeout(function ...
  • 所以在执行顺序上会先进行同步代码,再者Promise、Async/Await,最好setTimeout。 谈谈Promise、Async/Await差异 promise是resolve为异步方法,将放入微任务队里里执行,但是resolve前后的正常代码为同步代码;...
  • 由于事件循环优先级的存在,因此与任务队列(宏任务)(存储超时的setTimeout()回调)相比,作业队列(微任务)(用于存储已实现的Promise回调)的优先级更高。 https://segmentfault.com/a/1190000038769853 ...
  • 下面是今日头条的一道前端面试题:async function async1() {console.log("async1 start");await async2();console.log("async1 end");}async function async2() {console.log("async2");...setTimeout(fu...
  • Promise里的代码为什么比setTimeout先执行? 下面是一段代码,分析下面这段代码: var r = new Promise(function(resolve, reject){ console.log("a"); resolve() }); setTimeout(()=>console.log("d"), 0) r....
  • 此时没有同步任务,就去执行异步任务,因为setTimeout()的优先级低于promise,所以会优先执行promise队列。 此时异步队列任务顺序: setTimeout() - new Promise().resolve() - async2().resolve() ,setTimeout...
  • Promise, setTimeout 和 Event Loop 下面的代码段,为什么输出结果是1,2,3,5,4而非1,2,3,4,5?(function test() { setTimeout(function() {console.log(4)}, 0); new Promise(function executor(resolve) { console...
  • 关于setTimeOutPromise执行顺序的问题

    千次阅读 2019-03-07 17:18:19
    promise为es6引进的语言标准,为异步编程的一种解决方案; 阅读此文的前提是了解浏览器event loop的机制,还有promise的基本用法和特性,比如他自执行特性、状态不可逆特性等 任务队列中的宏观任务和微观任务 任务...
  • 实例 async function async1() { console.log('async1 start'); await async2(); console.log('async1 end'); } async function async2() { console.log('async2 ... setTimeout(function () { console.log
  • } //promise function method2(){ return new Promise(resolve=>{ setTimeout(function(){ resolve(); //resolve成功调用一次之后,后面的不会再执行 resolve(); },1000); }) } 控制反转。体现在对于函数的把控,...
  • 3.2.2 Promise结合setTimeout 3.3 事件循环中的async/await 4. 大综合(自测) 4.1 简单融合 4.2 变形1 4.3 变形2 4.4 变形3 5. 结语 JS中的事件循环原理以及异步执行过程这些知识点对新手来说可能有点难,但是是...
  • 宏任务包括:script(全局任务), setTimeout, setInterval, setImmediate, I/O, UI rendering 微任务包括: new Promise().then(回调), process.nextTick, MutationObserver(html5新特性) 1. 主进程必须是空闲的...
  • 简要介绍:谈谈promise.resove,setTimeout,setImmediate,process.nextTick在EvenLoop队列中的执行顺序 1.问题的引出 event loop都不陌生,是指主线程从“任务队列”中循环读取任务,比如 例1: setTimeout...
  • async function async1(){ console.log('async1 start') await async2() console.log('async1 end') } async function async2(){ ...setTimeout(function(){ console.log('setTimeout') },0) async1
  • microtask queue,setTimeout 的回调也是个 task 它会被放入 macrotask queue 即使是 0ms 的情况(microtask queue优先于macrotask queue ) 3 async await async function test(){ console.log('test in') ...
  • 1. setTimeout console.log('1 start') //1. 打印 script start setTimeout(function(){ console.log('settimeout') // 4. 打印 settimeout }) // 2. 调用 setTimeout 函数,并定义其完成后执行的回调函数 console...
  • 然而,执行 JavaScript 并非一锤子买卖,宿主环境当遇到一些事件时,会继续把一段代码传递给 JavaScript 引擎去执行,此外,我们可能还会提供 API 给 JavaScript 引擎,比如 setTimeout 这样的 API,它会允许 ...
  • 本期前端小知识介绍的是关于异步的内容,为什么 promise 会先于 setTimeout 执行小知识我们先来考虑下以下代码,你认为 log 的顺序是什么,如果你点击了页面会发送什么?f...
  • setTimeout(() =>console.log(1),0); console.log(2); const pro=new Promise(resolve=>{ console.log(3) setTimeout(()=>console.log(4),0) resolve(5) return Promise.r...
  • promise

    2016-10-24 22:24:13
    下面关于promise的说法中,错误的是()正确答案: D 你的答案: C (错误)resolve()和reject都是直接生成一个进入相应状态的promise对象,其参数就是进入相应状态时传递过去的参数,可以在完成回调的参数中得到...
  • 一道经典的前端笔试题,你能一眼写出他们的执行... 微任务:Promise,process.nextTick 微任务执行优先级高于宏任务,所以PromisesetTimeout优先执行。 理解了以上4个问题,那么这道笔试题也就容易理解了 最终结果:

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,864
精华内容 1,545
关键字:

promise优先settimeout