標籤: 電動車

  • this綁定方式總結

    最近在回顧js的一些基礎知識,把《你不知道的js》系列又看了一遍,this始終是重中之重,還是決定把this相關知識做一個系統的總結,也方便自己日後回顧。

    this的四條綁定規則

    1.默認綁定

    這是最常用的函數調用類型:獨立函數調用(即函數是直接使用不帶任何修飾的函數引用進行調用的)。可以把這條規則看作是無法應用其他規則時的默認規則。
    默認綁定的this在非嚴格模式下指向window,嚴格模式下指向undefined,比如下面的函數foo在非嚴格模式下:

    var a = 2;
    function foo(){
        var a = 3;
        console.log(this.a);
    }
    foo(); //2

    這裏的foo()方法內的this指向了window,因此window.a = 2;

    嚴格模式下,this.指向undefined,因此訪問this.a會報錯:

    var a = 2;
    function foo(){
        "use strict";
        var a = 3;
        console.log(this.a);
    }
    foo(); //Uncaught TypeError: Cannot read property 'a' of undefined

    2.隱式綁定

    如果調用位置上有上下文對象,或者說被某個對象“擁有”或者“包
    含”,則使用隱式綁定。

    function foo() {
        console.log( this.a );
    }
    var obj = {
        a: 2,
        foo: foo
    };
    obj.foo(); // 2

    上例中的foo是通過obj.foo()的方式調用的,調用位置會使用obj上下文來引用函數,因此foo中的this指向了obj。
    另外foo是當做引用被加入到obj中的,但是無論是直接在obj 中定義還是先定義再添加為引用屬性,foo嚴格上來說都不屬於obj,因此上述定義裏面的“擁有”與“包含”加上了引號,這樣說是為了方便理解。
    常見的隱式調用場景:
    obj.fn();
    arguments[i]();//其實就是將點的調用方式變為了[]調用
    el.onClick(function(){console.log(this);//this指向el})

    隱式丟失

    先來看一段代碼:

    function foo() {
        console.log( this.a );
    }
    var obj = {
        a: 2,
        foo: foo
    };
    var bar = obj.foo; // 函數別名!
    var a = "global"; // a 是全局對象的屬性
    bar(); // "global"

    上述代碼其實只用看調用的方式:bar(),這其實是一個不帶任何修飾的函數調用,因此應用了默認綁定。
    還有一種參數傳遞的方式也會發生隱式丟失,原理其實跟上述例子一樣:

    function foo() {
        console.log( this.a );
    }
    function doFoo(fn) {
        // fn 其實引用的是foo
        fn(); // <-- 調用位置!
    }
    var obj = {
        a: 2,
        foo: foo
    };
    var a = "global"; // a 是全局對象的屬性
    doFoo( obj.foo ); // "global"

    显示綁定

    使用call,apply和bind方法可以指定綁定函數的this的值,這種綁定方法叫显示綁定。

    function foo() {
        console.log( this.a );
    }
    var obj = {
        a:2
    };
    foo.call( obj ); // 2

    通過foo.call(obj),我們可以在調用foo 時強制把它的this 綁定到obj 上

    new綁定

    new操作符可以基於一個“構造函數”新創建一個對象實例,new的實例化過程如下:

    1. 創建(或者說構造)一個全新的對象。
    2. 這個新對象會被執行[[ 原型]] 連接。
    3. 這個新對象會綁定到函數調用的this。
    4. 如果函數沒有返回其他對象,那麼new 表達式中的函數調用會自動返回這個新對象。
      明確了new的實例化過程后,思考如下代碼:
    function foo(a) {
        this.a = a;
    }
    var bar = new foo(2);
    console.log( bar.a ); // 2

    new foo(2)后新創建了個實例對象bar,然後把這個新對象bar綁定到了foo函數中的this,因此執行this.a = a后其實是把a賦給了bar.a

    優先級

    一般情況下this的綁定會根據上述四條綁定規則來,那麼他們同時出現時,該以怎樣的順序來判斷this的指向?下面是具體的規則:

    1. 函數是否在new 中調用(new 綁定)?如果是的話this 綁定的是新創建的對象( var bar = new foo() )。
    2. 函數是否通過call、apply(顯式綁定)或者硬綁定調用?如果是的話,this 綁定的是指定的對象( var bar = foo.call(obj2) )。
    3. 函數是否在某個上下文對象中調用(隱式綁定)?如果是的話,this 綁定的是那個上下文對象。( var bar = obj1.foo() )
    4. 如果都不是的話,使用默認綁定。如果在嚴格模式下,就綁定到undefined,否則綁定到全局對象。( var bar = foo() )

    綁定例外

    1.使用call,appy,bind這種顯式綁定的方法,參數傳入null或者undefined作為上下文時,函數調用還是會使用默認綁定

    function foo() {
        console.log( this.a );
    }
    var a = 2;
    foo.call( null ); // 2

    什麼情況下需要將上下文傳為null呢?
    1.使用bind函數來實現柯里化

    function foo(a,b) {
        console.log(a,b);
    }
    // 使用 bind(..) 進行柯里化
    var bar = foo.bind( null, 2 );
    bar( 3 ); // 2,3

    2.使用apply(..) 來展開一個數組,併當作參數傳入一個函數

    function foo(a,b) {
        console.log(a,b);
    }
    // 把數組展開成參數
    foo.apply( null, [2, 3] ); // 2,3

    其實上面兩種使用場景其實都不關心call/app/bind第一個參數的值是什麼,只是想傳個佔位值而已。
    但是總是傳入null可能會出現一些難以追蹤的bug,比如說當你在使用的第三方庫中的某個函數中有this時,this會被錯誤的綁定到全局對象上,造成一些難以預料的後果(修改全局變量)

    var a = 1;//全局變量
    const Utils = {
        a: 2,
        changeA: function(a){
            this.a = a;
        }
    }
    Utils.changeA(3);
    Utils.a //3
    a //1
    Utils.changeA.call(null,4);
    Utils.a //3
    a //4,修改了全局變量a!

    更安全的做法:

    var o = Object.create(null);
    Utils.changeA.call(o,6);
    a //1, 全局變量沒有修改
    o.a // 6 改的是變量o

    2.間接引用

    function foo() {
        console.log( this.a );
    }
    var a = 2;
    var o = { a: 3, foo: foo };
    var p = { a: 4 };
    o.foo(); // 3
    (p.foo = o.foo)(); // 2

    賦值表達式p.foo = o.foo 的返回值是目標函數的引用,因此調用位置是foo() 而不是p.foo() 或者o.foo()。根據我們之前說過的,這裡會應用默認綁定。

    this詞法(箭頭函數)

    上述的幾種規則適用於所有的正常函數,但不包括ES6的箭頭函數。箭頭函數不使用this的四種標準規則,而是根據外層(函數或者全局)作用域(詞法作用域)來決定this

    function foo() {
    // 返回一個箭頭函數
        return (a) => {
            //this 繼承自foo()
            console.log( this.a );
        };
    }
    var obj1 = {
        a:2
    };
    var obj2 = {
        a:3
    };
    var bar = foo.call( obj1 );
    bar.call( obj2 ); // 2, 不是3 !

    foo() 內部創建的箭頭函數會捕獲調用時foo() 的this。由於foo() 的this 綁定到obj1,bar(引用箭頭函數)的this 也會綁定到obj1,箭頭函數的綁定無法被修改。(new 也不行!)

    幾個例子加深理解

    this的理論知識講解得差不多了,來幾個例子看看自己有沒有理解全面:
    1.經典面試題:以下輸出結果是什麼

    var length = 10;
    function fn() {
        console.log(this.length);
    }
    var obj = {
      length: 5,
      method: function(fn) {
        fn();
        arguments[0]();
      }
    };
    obj.method(fn, 1);

    obj中method方法裏面調用了兩次fn。第一次是直接調用的“裸露”的fn,因此fn()中this使用默認綁定,this.length為10.第二次調用時通過arguments的方式調用的,arguments[0]其實指向的就是fn,但是是通過obj[fn]這種對象上下文的隱式綁定的,因此this指向arguments,而arguments只有一個一項(method中只有fn一個參數),因此arguments.length為1。因此打印的結果為:

    10
    1

    2.以下輸出什麼

    var obj = {
        birth: 1990,
        getAge: function () {
            var b = this.birth; // 1990
            var fn = function () {
                return new Date().getFullYear() - this.birth; // this指向window或undefined
            };
            return fn();
        }
    };
    obj.getAge();

    答案是嚴格模式下會報錯,非嚴格模式下輸出NaN
    原因也是因為在調用obj.getAge()后,getAge方法內的this使用隱式綁定。但是return fn()的時候用的是“裸露的fn”使用默認綁定,fn裏面的this指向window或者undefined。
    使用箭頭函數來修正this的指向:

    var obj = {
        birth: 1990,
        getAge: function () {
            var b = this.birth; // 1990
            var fn = () => new Date().getFullYear() - this.birth; // this指向obj對象
            return fn();
        }
    };
    obj.getAge(); // 25

    使用箭頭函數后,fn中的this在他的詞法分析階段就已經確定好了(即fn定義的時候),跟調用位置無關。fn的this指向外層的作用域(即getAge中的this)
    3.以下輸出為什麼是’luo’

    var A = function( name ){ 
        this.name = name;
    };
    var B = function(){ 
        A.apply(this,arguments);
    };
    B.prototype.getName = function(){ 
        return this.name;
    };
    var b=new B('sven');  // B {name: "luo"}
    console.log( b.getName() ); // 輸出:  'luo'

    執行new B(‘seven’)後會返回一個新對象b,並且B函數中的this會綁定到新對象b上,B的函數體內執行A.apply(this.arguments)也就是執行b.name = name;這個時候b的值就是{name:’luo’},所以b.getName()就能輸出’luo’啦~

    實際在業務使用中,邏輯會更複雜一些,但是萬變不離其宗,都按照上面寫的規則來代入就好了

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

    ※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    ※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

  • 從零開始搭建前後端分離的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的項目框架之十二Swagger(參數)使用二

    從零開始搭建前後端分離的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的項目框架之十二Swagger(參數)使用二

      引言

      在 中提到了 Swagger 的基本使用,僅限於沒有參數,沒有驗證的那種api文檔生成,那麼這篇就連接上篇繼續,在一般具有安全性、權限等驗證的接口上,

      都會在header/url中加上請求者的秘鑰、簽名等,當然也有可能添加到body等其它地方, Swashbuckle.AspNetCore 都支持這些寫法。

      如何使用 — 下面將介紹兩種使用方式

    兩種方式參數設置到何處都是在  In屬性上,屬性對於值如下:    參考

    • query: 參数字段值對應放在url中
    • header: 參數值對應放在header param中
    • body: 參數對應放到請求體中
    • path: 參數應該對應放到請求路徑  // 具體貌似沒用
    • formData: 參數對應放到請求表單中

      第一種:將一個或多個參數保護API的“securityDefinitions”添加到生成的Swagger中。

    這種是直接在文檔的右上方添加一個 Authorize 按鈕,設置了值后,每一個請求都會在設置的位置上加上相應的值,在 上一篇隨筆中的 ConfigureServices 方法中,

    對應位置 services.AddSwaggerGen(options =>{}) 中的  XmlComments  下 添加代碼如下:

                    options.AddSecurityDefinition("token", new ApiKeyScheme
                    {
                        Description = "token format : {token}",//參數描述
                        Name = "token",//名字
                        In = "header",//對應位置
                        Type = "apiKey"//類型描述
                    });
                    options.AddSecurityDefinition("sid", new ApiKeyScheme
                    {
                        Description = "sid format : {sid}",//參數描述
                        Name = "sid",//名字
                        In = "header",//對應位置
                        Type = "apiKey"//類型描述
                    });
                    //添加Jwt驗證設置 設置為全局的,不然在代碼中取不到
                    options.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> {
                        { "token", Enumerable.Empty<string>() },
                        { "sid", Enumerable.Empty<string>() },
                    });

      添加完成后,運行起來看下效果,效果圖: 

     設置上對應值,調用測試方法,可以在header中取到剛設置到的值,

     這裡能看到,可以取到設置的參數了。這樣一來,在需要驗證的接口上,我們就可以通過接口文檔來測試了。基本不用再藉助postman等接口測試工具了。

    但是,但是,這裡有一個問題,就是只要設置了參數值,每一次訪問都會在請求中帶上參數。

    下面將介紹第二種方式,只給需要驗證用戶的接口上添加驗證參數。

      第二種:使用“filters”擴展Swagger生成器,來實現只在需要添加參數的方法上添加參數。複雜的可以根據自己的需求來添加對應參數

    實現方式就是先新建一個類,名: SwaggerParameter ,實現 IOperationFilter 接口。SwaggerParameter 類代碼如下: 

        /// <summary>
        /// 自定義添加參數
        /// </summary>
        public class SwaggerParameter : IOperationFilter
        {
            /// <summary>
            /// 實現 Apply 方法
            /// </summary>
            /// <param name="operation"></param>
            /// <param name="context"></param>
            public void Apply(Operation operation, OperationFilterContext context)
            {
                if (operation.Parameters == null) operation.Parameters = new List<IParameter>();
                var attrs = context.ApiDescription.ActionDescriptor.AttributeRouteInfo;
                var t = typeof(BaseUserController);
                //先判斷是否是繼承用戶驗證類
                if (context.ApiDescription.ActionDescriptor is ControllerActionDescriptor descriptor && context.MethodInfo.DeclaringType?.IsSubclassOf(t) == true)
                {
                    //再驗證是否允許匿名訪問
                    var actionAttributes = descriptor.MethodInfo.GetCustomAttributes(inherit: true);
                    bool isAnonymous = actionAttributes.Any(a => a is AllowAnonymousAttribute);
                    // 需要驗證的方法添加
                    if (!isAnonymous)
                    {
                        operation.Parameters.Add(new NonBodyParameter()
                        {
                            Name = "sid",
                            In = "header", //query header body path formData
                            Type = "string",
                            Required = true,//是否必選
                            Description = "登錄返回的sid"
                        });
                        operation.Parameters.Add(new NonBodyParameter()
                        {
                            Name = "token",
                            In = "header", //query header body path formData
                            Type = "string",
                            Required = true,//是否必選
                            Description = "登錄返回的token"
                        });
                    }
                }
            }
        }

     運行起來后,進入到  文檔頁面,可以看到右上角的 Authorize 按鈕已經不見了,在不需要驗證的方法上,也找不到相應需要設置參數的輸入框。就只有在需要驗證的接口上才有。

    參考Swagger文檔圖如下: 

    參考代碼圖如下:

     

    效果圖: 

      這樣一來設置也就完成了。從上面就能看出,就只有需要用戶驗證的接口才會有相應參數。 

     

    我的設置方式是先定義了用戶驗證控制器類,讓需要用戶驗證的控制器繼承該控制器,然後在該控制器中不需要用戶驗證的接口上加上 AllowAnonymous 屬性 

    設置fitter時就可以根據上面提到的兩個點來進行判斷是否需要加上參數,如果不是這樣實現的,可以根據自己的需求變更fitter類,來控制文檔的生成。 

     

    以上若有什麼不對或可以改進的地方,望各位指出或提出意見,一起探討學習~ 

    有需要源碼的可通過此 鏈接拉取 覺得還可以的給個 start 和點個 下方的推薦哦~~謝謝!

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

    ※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    ※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

  • pod刪除主要流程源碼解析

    本文以v1.12版本進行分析

    當一個pod刪除時,client端向apiserver發送請求,apiserver將pod的deletionTimestamp打上時間。kubelet watch到該事件,開始處理。

    syncLoop

    kubelet對pod的處理主要都是在syncLoop中處理的。

    func (kl *Kubelet) syncLoop(updates <-chan kubetypes.PodUpdate, handler SyncHandler) {
    for {
    ...
            if !kl.syncLoopIteration(updates, handler, syncTicker.C, housekeepingTicker.C, plegCh) {
                break
            }
    ...

    與pod刪除主要在syncLoopIteration中需要關注的是以下這兩個。

    func (kl *Kubelet) syncLoopIteration(configCh <-chan kubetypes.PodUpdate, handler SyncHandler,
        syncCh <-chan time.Time, housekeepingCh <-chan time.Time, plegCh <-chan *pleg.PodLifecycleEvent) bool {
        select {
        case u, open := <-configCh:
    ...
            switch u.Op {
    ...
            case kubetypes.UPDATE:
                handler.HandlePodUpdates(u.Pods)
    ...
        case <-housekeepingCh:
            if !kl.sourcesReady.AllReady() {
            } else {
                if err := handler.HandlePodCleanups(); err != nil {
                    glog.Errorf("Failed cleaning pods: %v", err)
                }
            }
        }

    第一個是由於發送給apiserver的DELETE請求觸發的,增加了deletionTimestamp的事件。這裏對應於kubetypes.UPDATE。也就是會走到HandlePodUpdates函數。

    另外一個與delete相關的是每2s執行一次的來自於housekeepingCh的定時事件,用於清理pod,執行的是handler.HandlePodCleanups函數。這兩個作用不同,下面分別進行介紹。

    HandlePodUpdates

    先看HandlePodUpdates這個流程。只要打上了deletionTimestamp,就必然走到這個流程里去。

    func (kl *Kubelet) HandlePodUpdates(pods []*v1.Pod) {
        for _, pod := range pods {
    ...
            kl.dispatchWork(pod, kubetypes.SyncPodUpdate, mirrorPod, start)
        }
    }

    在HandlePodUpdates中,進而將pod的信息傳遞到dispatchWork中處理。

    func (kl *Kubelet) dispatchWork(pod *v1.Pod, syncType kubetypes.SyncPodType, mirrorPod *v1.Pod, start time.Time) {
        if kl.podIsTerminated(pod) {
            if pod.DeletionTimestamp != nil {
                kl.statusManager.TerminatePod(pod)
            }
            return
        }
        // Run the sync in an async worker.
        kl.podWorkers.UpdatePod(&UpdatePodOptions{
            Pod:        pod,
            MirrorPod:  mirrorPod,
            UpdateType: syncType,
            OnCompleteFunc: func(err error) {
    ...

    這裏首先通過判斷了kl.podIsTerminated(pod)判斷pod是不是已經處於了Terminated狀態。如果是的話,則不進行下面的kl.podWorkers.UpdatePod。

    func (kl *Kubelet) podIsTerminated(pod *v1.Pod) bool {
        status, ok := kl.statusManager.GetPodStatus(pod.UID)
        if !ok {
            status = pod.Status
        }
        return status.Phase == v1.PodFailed || status.Phase == v1.PodSucceeded || (pod.DeletionTimestamp != nil && notRunning(status.ContainerStatuses))
    }

    這個地方特別值得注意的是,並不是由了DeletionTimestamp就會認為是Terminated狀態,而是有DeletionTimestamp且所有的容器不在運行了。也就是說如果是一個正在正常運行的pod,是也會走到kl.podWorkers.UpdatePod中的。UpdatePod通過一系列函數調用,最終會通過異步的方式執行syncPod函數中進入到syncPod函數中。

    func (kl *Kubelet) syncPod(o syncPodOptions) error {
    ...
        if !runnable.Admit || pod.DeletionTimestamp != nil || apiPodStatus.Phase == v1.PodFailed {
            var syncErr error
            if err := kl.killPod(pod, nil, podStatus, nil); err != nil {
    ...

    在syncPod中,調用killPod從而對pod進行停止操作。

    killPod

    killPod是停止pod的主體。在很多地方都會使用。這裏主要介紹下起主要的工作流程。停止pod的過程主要發生在killPodWithSyncResult函數中。

    func (m *kubeGenericRuntimeManager) killPodWithSyncResult(pod *v1.Pod, runningPod kubecontainer.Pod, gracePeriodOverride *int64) (result kubecontainer.PodSyncResult) {
        killContainerResults := m.killContainersWithSyncResult(pod, runningPod, gracePeriodOverride)
    ...
        for _, podSandbox := range runningPod.Sandboxes {
                if err := m.runtimeService.StopPodSandbox(podSandbox.ID.ID); err != nil {
    ...

    killPodWithSyncResult的主要工作分為兩個部分。killContainersWithSyncResult負責將pod中的container停止掉,在停止后再執行StopPodSandbox。

    func (m *kubeGenericRuntimeManager) killContainer(pod *v1.Pod, containerID kubecontainer.ContainerID, containerName string, reason string, gracePeriodOverride *int64) error {
        if err := m.internalLifecycle.PreStopContainer(containerID.ID); err != nil {
            return err
        }
    ...
        err := m.runtimeService.StopContainer(containerID.ID, gracePeriod)

    killContainersWithSyncResult的主要工作是在killContainer中完成的,這裏可以看到,其中的主要兩個步驟是在容器中進行prestop的操作。待其成功后,進行container的stop工作。至此所有的應用容器都已經停止了。下一步是停止pause容器。而StopPodSandbox就是執行這一過程的。將sandbox,也就是pause容器停止掉。StopPodSandbox是在dockershim中執行的。

    func (ds *dockerService) StopPodSandbox(ctx context.Context, r *runtimeapi.StopPodSandboxRequest) (*runtimeapi.StopPodSandboxResponse, error) {
    ...
    if !hostNetwork && (ready || !ok) {
    ...
            err := ds.network.TearDownPod(namespace, name, cID, annotations)
    ...
        }
        if err := ds.client.StopContainer(podSandboxID, defaultSandboxGracePeriod); err != nil {

    StopPodSandbox中主要的部分是先進行網絡卸載,再停止相應的容器。在完成StopPodSandbox后,至此pod的所有容器都已經停止完成。至於volume的卸載,是在volumeManager中進行的。本文不做單獨介紹了。停止后的容器在pod徹底清理后,會被gc回收。這裏也不展開講了。

    HandlePodCleanups

    上面這個流程並不是刪除流程的全部。一個典型的情況就是,如果container都不是running,那麼在UpdatePod的時候都return了,那麼又由誰來處理呢?這裏我們回到最開始,就是那個每2s執行一次的HandlePodCleanups的流程。也就是說比如container處於crash,container正好不是running等情況,其實是在這個流程里進行處理的。當然HandlePodCleanups的作用不僅僅是清理not running的pod,再比如數據已經在apiserver中強制清理掉了,或者由於其他原因這個節點上還有一些沒有完成清理的pod,都是在這個流程中進行處理。

    func (kl *Kubelet) HandlePodCleanups() error {
    ... 
        for _, pod := range runningPods {
            if _, found := desiredPods[pod.ID]; !found {
                kl.podKillingCh <- &kubecontainer.PodPair{APIPod: nil, RunningPod: pod}
            }
        }

    runningPods是從cache中獲取節點現有的pod,而desiredPods則是節點上應該存在未被停止的pod。如果存在runningPods中有而desiredPods中沒有的pod,那麼它應該被停止,所以發送到podKillingCh中。

    func (kl *Kubelet) podKiller() {
    ...
        for podPair := range kl.podKillingCh {
    ...
    
            if !exists {
                go func(apiPod *v1.Pod, runningPod *kubecontainer.Pod) {
                    glog.V(2).Infof("Killing unwanted pod %q", runningPod.Name)
                    err := kl.killPod(apiPod, runningPod, nil, nil)
    ...
                }(apiPod, runningPod)
            }
        }
    }

    在podKiller流程中,會去接收來自podKillingCh的消息,從而執行killPod,上文已經做了該函數的介紹了。

    statusManager

    在最後,statusManager中的syncPod流程,將會進行檢測,通過canBeDeleted確認是否所有的容器關閉了,volume卸載了,cgroup清理了等等。如果這些全部完成了,則從apiserver中將pod信息徹底刪除。

    func (m *manager) syncPod(uid types.UID, status versionedPodStatus) {
    ...
        if m.canBeDeleted(pod, status.status) {
            deleteOptions := metav1.NewDeleteOptions(0)
            deleteOptions.Preconditions = metav1.NewUIDPreconditions(string(pod.UID))
            err = m.kubeClient.CoreV1().Pods(pod.Namespace).Delete(pod.Name, deleteOptions)
    ...

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

    ※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    ※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

  • 氫燃料沒未來?Honda改拚電動車,明年搶攻歐陸

    氫燃料沒未來?Honda改拚電動車,明年搶攻歐陸

    本田汽車(Honda)計畫於2018年一次推出兩款全電動車,且宣告未來將以電動車作為發展主軸。

    根據《BusinessInsider》報導表示,本田六月就已表示將打造中國專屬電動車,8月29日發佈的聲明稿則指明另一款電動車是為歐洲客戶所設計。

    本田說,新城市電動概念車(Urban EV Concept)將在九月法蘭克福車展上亮相,這也是本田在歐洲第一款電動車,肩負打開歐洲電動車市場的任務。

    目前本田僅有一款純電動車在美國上市,不過本田表示,2030年旗下三分之二的車型都要電動化,達成目標的方法將在法蘭克福車展上對外說明。

    本田與日本同業豐田(Toyota)此前主要開發氫燃料車與混和動力車,但由上述可知本田策略已經轉向發展電動車,可能引領其它日本車廠跟進。

    (本文內容由授權使用。圖片出處:)

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

    ※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    ※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

  • DuckDuckGo切換到蘋果地圖

    DuckDuckGo切換到蘋果地圖

      匿名搜索引擎 DuckDuckGo 宣布地圖和地址相關的搜索將使用蘋果地圖。Google 被認為是一大隱私威脅,顯然以隱私作為主要賣點的 DuckDuckGo 不能也應該使用 Google 地圖。它可以選擇的全球地圖只剩下蘋果地圖、OpenStreetMap 和必應地圖等不多的幾個選擇。Google 地圖在功能和細節上仍然是最出色的,蘋果地圖的美國地圖足夠精細,但在其它國家它的地圖準確性就並不那麼令人滿意了。

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

    ※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

    ※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※帶您來看台北網站建置台北網頁設計,各種案例分享

  • 趨勢無法擋!BMW、JLR宣布自2020年起力推電動車

    趨勢無法擋!BMW、JLR宣布自2020年起力推電動車

    Thomson Reuters報導,英國最大汽車製造商Jaguar Land Rover(JLR)7日宣布,2020年起旗下所有新車都將具備電動或油電混合驅動選項。英國跟隨法國以及馬德里、墨西哥城和雅典等城市的抗空汙腳步,7月宣布將自2040年起禁止販售汽油和柴油新車。

    德國車廠BMW 7日宣布將自2020年起開始量產電動車、預估到2025年將有12種純電動車款。BMW執行長Harald Krueger表示,電動車續航力將上看700公里。電池成本約占電動車造價的30到50%。巴克萊(Barclays)預估電池產能的大幅提升將可令電動車、內燃引擎車在2020到2030年間達到「成本平價」。ING預估歐洲有望在2035年成為100%的電動車市場。

    BBC News報導,BMW研發部負責人Klaus Froehlich 日前表示,電動移動趨勢是不可逆轉的,自2020年起BMW所有車款都將擁有電動驅動選項。

    (本文內容由授權使用。)

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

    ※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    ※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

  • 雷諾日產2022目標:推零排放電動車、降低車用鋰電池成本30%

    雷諾日產2022目標:推零排放電動車、降低車用鋰電池成本30%

    特斯拉(Tesla Inc.)讓電動車產業起了大震盪,發展愈來愈快,雷諾日產聯盟(The Renault-Nissan Alliance)也不落人後,聲稱2020年將發表12款零排放電動車,同時還要推出機器人計程車(robo-taxi),提供無人駕駛的叫車服務。

    CNBC報導,雷諾日產聯盟董事長兼執行長、三菱汽車董事長戈恩(Carlos Ghosn)15日在接受專訪時表示,集團擬定的六年新計畫「Alliance 2022」,除了要發表零排放電動車、機器人計程車之外,也會推出40款自駕程度不等的汽車款式。

    戈恩說,機器人計程車主要是商業用途,許多像是Uber等業者,對此都有極高需求。另外,戈恩也打算將雷諾、日產與三菱汽車的合作綜效倍增,預估2022年聯盟的年營收,將從原本的50億歐元拉高至100億歐元;到了2022年,三大車廠的合併汽車銷售量,有望從2016年的1,000萬台、1,050萬台進一步增加至1,400萬台。
    目前聯盟的主要目標,是降低車用電池的成本,希望能在2022年底前,將成本降低30%,單次充電時間壓縮到15分鐘、每次充電可行駛的里程數增加至230公里。戈恩說,集團已經評估過鋰的產能,估計未來5-6年內,應該都不會有瓶頸出現。

    先前已有消息指稱,中國打算禁用、禁產傳統汽油車。新華社9月9日報導,中國工信部副部長辛國斌表示,一些國家已經制定了停止生產銷售傳統能源汽車的時間表。他說,目前工信部也啟動了相關研究、將會同相關部門制定中國的時間表。

    Fortune 11日報導,目前北京當局並未對何時要進行轉換設定時間表。其他國家則打算在2030年左右逐步將汽油車淘汰:印度的目標設定在2030年、但並不是嚴格執行的時間點,至於英國、法國與挪威的預定目標則分別是2040年、2040年與2025年。

    澳洲礦商Orocobre Limited最近才聲稱鋰礦需求強、報價攀高,將擴產碳酸鋰。barron`s.com、The Australian報導,Orocobre執行長Richard Seville 8月底說,全球鋰礦市場的基本面依舊穩健,不但需求強勁、供給吃緊,報價也相當具有吸引力。為了滿足特定電池夥伴的需求,Orocobre會分階段擴充Olaroz鋰礦廠的產能。

    依據Orocobre計畫,位於阿根廷的Olaroz鋰礦廠,產能料將倍增。另外,該公司還會跟豐田通商(Toyota Tsusho Corporation)一同打造一座廠房,預計將年產10,000公噸的氫氧化鋰(lithium hydroxide)。

    (本文內容由授權使用)

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

    ※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    ※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

  • 戴森宣示砸20億英鎊開發電動車、拚2020年公開亮相

    戴森宣示砸20億英鎊開發電動車、拚2020年公開亮相

    戴森公司(Dyson)創辦人James Dyson 26日宣布,戴森開發中的電動車預計在2020年推出。Dyson預計投入20億英鎊開發電池驅動車、目前已打造出一支超過400人的研發團隊。他表示,汽車業競爭相當激烈、因此現階段無法對外公布更多細節。

    倫敦國王學院研究人員發現,倫敦每年因長期遭受空氣污染而早死的人數逼近9,500人。世界衛生組織(WHO)報告顯示,2012年約有700萬人因暴露於空氣污染環境而死亡。

    Thomson Reuters報導,Dyson 26日透露,研發團隊已經花了2.5年的時間在英國馬姆斯伯里(Malmesbury)開發固態電池技術。他還沒決定要在何處生產戴森電動車,但可以確定的是不會跟任何汽車製造商合作。

    《日經亞洲評論》於2016年3月報導,戴森於2015年收購自密西根大學分割出來的固態電池技術開發公司Sakti3。戴森執行長Max Conze當時表示、希望3-5年內在能源儲存密度領域能夠有突破性的進展。

    forbes.com 9月26日報導,與特斯拉(Tesla)執行長馬斯克(Elon Musk)不同的是,James Dyson已經擁有開發成功、可獲利消費性商品的紀錄。戴森產品包括吸塵器、吹風機、空氣清淨器、節能照明設備等等。

    戴姆勒(Daimler AG)卡車部門9月14日宣布投資以色列奈米技術材料新創公司StoreDot Ltd.。cityam.com 5月報導,StoreDot名列百大最具破壞性新創企業第一名。

    StoreDot官網顯示,採用FlashBattery技術的新世代電池僅需5分鐘就能完成充電工作、提供電動車多達300英里(480公里)的續航力,相當於充電1分鐘就能讓電動車跑60英里。

    CNBC 9月5日報導,豐田汽車公司會長內山田竹志(Takeshi Uchiyamada)在接受專訪時表示,基於當前電池技術的侷限、他懷疑消費者會立即投向電動車的懷抱。內山田表示,豐田不是排斥電動車,但為了要提供足夠的續航力、電動車目前需要安裝許多電池並得花相當長的時間去充電,而且電池壽命也是一大問題。內山田認為車輛全面由電池驅動之前、還須經歷2-3次的技術性突破才行。

    (本文內容由授權使用)  

     

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

    ※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    ※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

  • 電動車不夠看!英美研發電動飛機、預計10年內升空

    電動車不夠看!英美研發電動飛機、預計10年內升空

     

    電動車蔚為風潮,再來電動飛機將佔領天空?歐洲航空業者EasyJet和美國新創企業Wright Electric合作,準備打造電動飛機,預計十年內飛上雲霄。

    CNNMoney、CNBC報導,EasyJet 27日宣布攜手Wright Electric,打造航程為335英里(539公里)的電動客機,負責短程航班,如紐約飛往波士頓、或倫敦飛往巴黎等。EasyJet為廉價航空,多以短途航程為主,電動客機可涵蓋該公司的20%航班。

    EasyJet希望電動客機能在十年間升空。該公司執行長Carolyn McCall說,他們預想的未來沒有石化燃料。對電動客機,眾人想問的不是能否成真,而是何時現身。

    2016年電池化學家、航太工程師、電動車專家成立Wright Electric,並獲得哈佛大學和知名新創公司孵化器Y Combinator注資。Wright Electric的目標是,未來20年所有的短程飛行都由電動客機運載,達到零廢氣排放。

    歐盟執委會曾說,航空業排放大量的溫室氣體,是成長最快的廢氣來源之一。

    (本文內容由授權使用。圖片出處:pixabay CC0)

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

    ※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    ※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

  • 塔塔電力擬興建1千座充電站,助印度汰除汽柴油車

    塔塔電力擬興建1千座充電站,助印度汰除汽柴油車

    日經新聞周二報導,印度最大民營電廠塔塔電力(Tata Power)計畫未來五年將於印度首都建造一千座充電站,藉以響應政府2030年禁用汽柴油車的政策。

    塔塔電力目前只有五座充電站在營運,印度全國充電站加總起來也不過100座左右,由此可知印度發展電動車的基礎設施嚴重不足,增加充電站密度勢在必行。

    據塔塔電力執行長Praveer Sinha表示,一千個新充電站都將設置在新德里北部地區,預估將花費10億印度盧比(1,520萬美元),每個充電站有九成服務鉛電池車,一成服務鋰電池車。

    (本文內容由授權使用)

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

    ※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    ※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益