• vue.js源码学习分享(六)


    /*  */
    /* globals MutationObserver *///全局变化观察者
    
    // can we use __proto__?//我们能用__proto__吗?
    var hasProto = '__proto__' in {};
    
    // Browser environment sniffing//浏览器环境嗅探
    var inBrowser = typeof window !== 'undefined';//是不是在浏览器中
    var UA = inBrowser && window.navigator.userAgent.toLowerCase();
    var isIE = UA && /msie|trident/.test(UA);//是不是IE浏览器   内核为trident
    var isIE9 = UA && UA.indexOf('msie 9.0') > 0;//是不是IE9
    var isEdge = UA && UA.indexOf('edge/') > 0;
    var isAndroid = UA && UA.indexOf('android') > 0;
    var isIOS = UA && /iphone|ipad|ipod|ios/.test(UA);
    var isChrome = UA && /chrome/d+/.test(UA) && !isEdge;
    
    // this needs to be lazy-evaled because vue may be required before
    // vue-server-renderer can set VUE_ENV//这里需要被懒运算,因为vue可能被需要在 vue服务渲染器设置VUE_ENVz之前
    var _isServer;
    var isServerRendering = function () {
      if (_isServer === undefined) {
        /* istanbul ignore if */
        if (!inBrowser && typeof global !== 'undefined') {
          // detect presence of vue-server-renderer and avoid
          // Webpack shimming the process
          _isServer = global['process'].env.VUE_ENV === 'server';
        } else {
          _isServer = false;
        }
      }
      return _isServer
    };
    
    // detect devtools//探测开发工具
    var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
    
    /* istanbul ignore next */
    function isNative (Ctor) {//判断是不是本地的方法
      return /native code/.test(Ctor.toString())
    }
    
    var hasSymbol =
      typeof Symbol !== 'undefined' && isNative(Symbol) &&
      typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys);
    
    /**
     * 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(要么本机的promise).then or MutationObserver(html5新特性之一Mutation Observer(变动观察器)是监视DOM变动的接口。当DOM对象树发生任何变动时,Mutation Observer会得到通知。).
    // MutationObserver has wider support, however it is seriously bugged in//变动观察器具有广泛的支持,然而它被严重的干扰在苹果9.3.3以上系统的网页中,当触摸事件被触发时
    // 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是有效的,我们将会使用promise。
    // Promise is available, we will use it:
    /* istanbul ignore if */
    if (typeof Promise !== 'undefined' && isNative(Promise)) {//如果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//在有问题的网页中,Promise.then 不会完全的销毁,但是它会被卡住在一个不可思议的状态下
    // 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 (typeof MutationObserver !== 'undefined' && (//判断是否支持“变动观察器”
    isNative(MutationObserver) ||
    // PhantomJS and iOS 7.x
    MutationObserver.toString() === '[object MutationObserverConstructor]'
    )) {
    // use MutationObserver where native Promise is not available,//在本地Promise无效的情况下使用“变动观察器”
    // e.g. PhantomJS IE11, 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);
    };
    }

    return function queueNextTick (cb, ctx) {
    var _resolve;
    callbacks.push(function () {
    if (cb) { cb.call(ctx); }
    if (_resolve) { _resolve(ctx); }
    });
    if (!pending) {
    pending = true;
    timerFunc();
    }
    if (!cb && typeof Promise !== 'undefined') {
    return new Promise(function (resolve) {
    _resolve = resolve;
    })
    }
    }
    })();
     
  • 相关阅读:
    Styles和Themes
    Activity返回值
    Android BaseAdapter 例子
    Android流量统计TrafficStats类的使用
    Javascript屏蔽IE和Firefox浏览器默认按键响应(快捷键功能)
    拍照技巧笔记
    android开发录音和播放录音的例子
    Eclipse快捷键大全(android开发)
    Android SQLite 添加、更新和删除行
    绑定Enum到ASP.NET数据绑定控件的完美解决方案[05/26修订]——增加支持第三方枚举描述,支持二进制与过的枚举值
  • 原文地址:https://www.cnblogs.com/liuhao-web/p/6670007.html
Copyright © 2020-2023  润新知