分類
發燒車訊

.NET Core請求控制器Action方法正確匹配,但為何404?

前言

有些時候我們會發現方法名稱都正確匹配,但就是找不到對應請求接口,所以本文我們來深入了解下何時會出現接口請求404的情況。

匹配控制器Action方法(404)

首先我們創建一個web api應用程序,我們給出如下示例控制器代碼

[ApiController]
[Route("[controller]/[action]")]
public class WeatherController : ControllerBase
{
    [HttpGet]
    string Get()
    {
        return "Hello World";
    }
}

 

當我們進行如上請求時會發現接口請求不到,這是為何呢?細心的你應該可能發現了,對於請求方法是私有,而不是公共的,當我們加上public就可以請求到了接口

[HttpGet("get")]
public string Get()
{
    return "Hello World";
}

匹配控制器Action方法本質

經過如上示例,那麼對於Action方法的到底要滿足怎樣的定義才能夠不至於請求不到呢?接下來我們看看源碼怎麼講。我們找到DefaultApplicationModelProvider類,在此類中有一個OnProvidersExecuting方法用來構建控制器和Action方法模型,當我們構建完畢所有滿足條件的控制器模型后,緊接着勢必會遍歷控制器模型去獲取對應控制器模型下的Action方法,這裏只截取獲取Action方法片段,源碼如下:

foreach (var controllerType in context.ControllerTypes)
{    
    //獲取控制器模型下的Action方法
    foreach (var methodInfo in controllerType.AsType().GetMethods())
    {
        var actionModel = CreateActionModel(controllerType, methodInfo);
        if (actionModel == null)
        {
            continue;
        }

        actionModel.Controller = controllerModel;
        controllerModel.Actions.Add(actionModel);    
    }
}

上述紅色標記則是創建Action模型的重點,我們繼續往下看到底滿足哪些條件才創建Action模型呢?

protected virtual ActionModel CreateActionModel(TypeInfo typeInfo, MethodInfo methodInfo)
{
    if (typeInfo == null)
    {
        throw new ArgumentNullException(nameof(typeInfo));
    }

    if (methodInfo == null)
    {
        throw new ArgumentNullException(nameof(methodInfo));
    }

    if (!IsAction(typeInfo, methodInfo))
    {
        return null;
    }    
    ......    
}

到了這個方法裏面,我們找到了如何確定一個方法為Action方法的源頭,由於該方法有點長,這裏我採用文字敘述來作為判斷邏輯,如下:

protected virtual bool IsAction(TypeInfo typeInfo, MethodInfo methodInfo)
{
    //如果有屬性訪問器(無效)

    //如果有NonAction特性標識無效)

    //如果重寫Equals(Object), GetHashCode()方法(無效)

    //如果實現Dispose方法(無效)

    //如果是靜態方法(無效)

    //如果是抽象方法(無效)

    //如果是構造函數(無效)

    //如果是泛型方法(無效)

    //必須為公共方法
    return methodInfo.IsPublic;
}

如上是從方法定義的角度來過濾而獲取Action方法,除此之外,我們請求方法的名稱還可以自定義,比如通過路由、ActionName特性指定,那麼這二者是否存在優先級呢?比如如下示例:

[ApiController]
[Route("[controller]/[action]")]
public class WeatherController : ControllerBase
{
    [HttpGet]
    [ActionName("get1")]
    public string get()
    {
        var routeValue = HttpContext.Request.RouteValues.FirstOrDefault();

        return routeValue.Value.ToString();
    }
}

我們可以看到此時將以ActionName特性作為方法名稱。所以在上述過濾方法定義后開始構建方法模型,在此之後還會再做一步操作,那就是查找該方法是否通過ActionName特性標識,若存在則以ActionName特性標識給定的名稱作為請求方法名稱,否則以方法定義名稱為準,源碼如下:

var actionModel = new ActionModel(methodInfo, attributes);

AddRange(actionModel.Filters, attributes.OfType<IFilterMetadata>());

var actionName = attributes.OfType<ActionNameAttribute>().FirstOrDefault();
if (actionName?.Name != null)
{
    actionModel.ActionName = actionName.Name;
}
else
{
    actionModel.ActionName = methodInfo.Name;
}

還沒完,若是將路由特性放到Action方法上,如下,此時請求接口應該是weather/get還是weather/get1呢?

[ApiController]
public class WeatherController : ControllerBase
{
    [HttpGet]
    [Route("weather/get")]
    [ActionName("get1")]
    public string get()
    {
        var routeValue = HttpContext.Request.RouteValues.FirstOrDefault();

        return routeValue.Value.ToString();
    }
}

此時若我們以weather/get1請求將出現404,還是以路由特性模板給定為準進行請求,但最終會將路由上Action方法名稱通過ActionName特性上的名稱賦值給Action模型中的ActionName進行覆蓋,源碼如下,所以上述我們得到的action名稱為get1,,當然這麼做沒有任何實際意義。

public static void AddRouteValues(ControllerActionDescriptor actionDescriptor,ControllerModel controller,ActionModel action)
{
    foreach (var kvp in action.RouteValues)
    {
        if (!actionDescriptor.RouteValues.ContainsKey(kvp.Key))
        {
            actionDescriptor.RouteValues.Add(kvp.Key, kvp.Value);
        }
    }

    if (!actionDescriptor.RouteValues.ContainsKey("action"))
    {
        actionDescriptor.RouteValues.Add("action", action.ActionName ?? string.Empty);
    }

    if (!actionDescriptor.RouteValues.ContainsKey("controller"))
    {
        actionDescriptor.RouteValues.Add("controller", controller.ControllerName);
    }
}

總結

本文我們只是單獨針對查找Action方法名稱匹配問題做了進一步的探討,根據源碼分析,對Action方法名稱指定會做3步操作:第一,根據方法定義進行過濾篩選,第二,若方法通過AcionName特性標識則以其所給名稱為準,否則以方法名稱為準,最終賦值給ActionModel上的ActionName屬性,第三,將ActionModel上的ActionName值賦值給路由集合中的鍵Action。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

※教你寫出一流的銷售文案?

分類
發燒車訊

BMW 高階電動車 i3 與 i8 正式登陸

BMW Corp  21 日首度針對中國大陸消費者行銷純電動車「i3 」,讓當地剛剛萌芽的高階電動車市場競爭開始升級。   華爾街日報 22 日報導,i3 21 日在大陸正式開賣、定價約 73,000 美元。i3 是 BMW 在大陸第一款純電動車,電動車製造商特斯拉 (Tesla) 才剛在 4 月份將大陸第一台「Model S」電動車交給當地顧客。Model S 在大陸的定價約 121,000 美元。   BMW 雖然並未透露正式的銷售目標,但該公司中國分部執行長 Karsten Engel 曾在 4 月表示,BMW 希望 2014 年能在當地賣出 1,000 台左右的 i3 與 i8。BMW 目前已經在北京、上海、深圳以及瀋陽指定了 7 家經銷商。   特斯拉成長動能逐漸趨緩,得在亞洲(尤其是大陸)加把勁,才能達成 2014 年預設的銷售目標。現在 BMW 又來搶食大餅,特斯拉可得趕緊擬定對策了。  

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

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

分類
發燒車訊

大陸代工給鴻海?特斯拉駁斥傳言

美國電動車廠特斯拉交貨能力大幅提升,出現逾 7 成的成長,面對會否將代工業務拉回大陸時,特斯拉卻傾向冷處理,甚至還主動發出官方回應,強調「目前沒有在大陸代工生產的計畫」,看來先前外界傳出鴻海要在中國替 Tesla 代工電動車的合作計畫,恐怕還要再等一等。   特斯拉 2013 年共交付 2 萬輛 Model S,2014 年有機會上看 3.5 萬輛,市場將特斯拉交貨能力大增原因指向生產線的擴展,特斯拉美國生產基地最近又新增了一條生產線,周產能達 1,000 輛。   除了在美擴充生產線,會否將代工產線拉回大陸,也成了市場關注焦點,但對此,特斯拉卻傾向冷處理,還特別發出官方回應,強調「特斯拉現所有在華銷售的車輛都是在美國生產,再進口到中國,目前沒有在大陸代工生產的計畫。」  

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

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

分類
發燒車訊

衣索比亞總理阿邁德推動環保、性平獲2019年諾貝爾和平獎

貝爾和平獎11日出爐,得獎者是衣索比亞總理阿邁德(Abiy Ahmed),原因是他結束該國與鄰國厄利垂亞之間長達20年的戰火,這項創舉又激發了非洲地區一系列的外交突破,阿邁德也提倡性別平等、環境保護。

阿邁德2018年4月上任,是該國第1位奧羅莫元首,在最初幾個月,他果斷、大膽地釋放政治犯,並對他們受到的酷刑予以譴責,也釋放被監禁的記者,甚至與政治反對派、民間社會對談,討論改革問題,並邀請先前流亡的政黨人士返國,還針對安全、司法部門進行重大改革。

阿邁德也致力於性別、環保問題,例如在國境內植樹造林以遏制氣候變化的負面影響。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

※教你寫出一流的銷售文案 ?

分類
發燒車訊

BERT的前世今生

Transformer

Transformer來自論文: All Attention Is You Need

別人的總結資源:

  1. 谷歌官方AI博客: Transformer: A Novel Neural Network Architecture for Language Understanding
  2. Attention機制詳解(二)——Self-Attention與Transformer谷歌軟件工程師
  3. 放棄幻想,全面擁抱Transformer:自然語言處理三大特徵抽取器(CNN/RNN/TF)比較中科院軟件所 · 自然語言處理 /搜索 10年工作經驗的博士(阿里,微博);
  4. Calvo的博客:Dissecting BERT Part 1: The Encoder,儘管說是解析Bert,但是因為Bert的Encoder就是Transformer,所以其實它是在解析Transformer,裏面舉的例子很好;
  5. 再然後可以進階一下,參考哈佛大學NLP研究組寫的“The Annotated Transformer. ”,代碼原理雙管齊下,講得也很清楚。
  6. 《Attention is All You Need》淺讀(簡介+代碼)這個總結的角度也很棒。

A High-Level Look

可以將輸入的語言序列轉換成另外一種序列,比如下圖的神經機器翻譯:

Transformer模型由編碼器-解碼器組合組成,解碼器負責對序列進行編碼,提取時間和空間信息,解碼器負責利用時間和空間特徵信息進行上下文預測,下圖是單個結構:

編碼器和解碼器堆棧的組合結構,在谷歌的實驗結構中採用了6個編碼器和6解碼器相對應,使模型的編碼能力和解碼能力達到一個平衡狀態(堆棧式結構):

編碼器-解碼器的內部結構,類似seq2seq模型:

seq2seq模型:

Encoder: 由6個相同的層組成, 每層包含兩個sub-layers.第一個sub-layer就是multi-head attention layer,然後是一個簡單的全連接層。其中每個sub-layer都加了residual connection(殘差連接)和normalisation(歸一化)。

Decoder: 由6個相同的層組成,這裏的layer包含三個sub-layers, 第一個sub-layer 是masked multi-head attention layer。這裡有個特別點就是masked, 作用就是防止在訓練的時候,使用未來的輸出的單詞。比如訓練時,第一個單詞是不能參考第二個單詞的生成結果的。Masked是在點乘attention操作中加了一個mask的操作,這個操作是保證softmax操作之後不會將非法的values連到attention中,提高泛化性。

Self-Attention at a High Level

假設下面的句子就是我們需要翻譯的輸入句:

”The animal didn’t cross the street because it was too tired”

當模型處理單詞的時候,self attention層可以通過當前單詞去查看其輸入序列中的其他單詞,以此來尋找編碼這個單詞更好的線索。

Self-Attention in Detail

第一步是將輸入的嵌入詞向量通過三個不同的參數矩陣得到三個向量,分別是一個Query向量,一個Key向量和一個Value向量,參數矩陣分別為Wq,Wk,Wv,,如下圖所示:

第二步是通過當前詞的q向量與其他詞的k向量計算當前詞相對於其他詞的得分,分數採用點積進行計算,如下圖所示:

第三步和第四步是講得到的分數除以k值維數的平方根(k值維數為64,可以使訓練過程有更加穩定的梯度,這個歸一化的值是經驗所得),再通過softmax得到每個得分的標準化得分:

第五步是對當前詞所得到的標準化值對所有value向量進行加權求和得到當前詞的attention向量,這樣就使不同單詞的嵌入向量有了attention的參与,從而預測上下文句子的時候體現不同的重要的重要程度。

Matrix Calculation of Self-Attention

  • Attendtion向量計算的矩陣形式,通過全職矩陣進行詞向量的計算大大加快了神經網絡的速度

  • X矩陣中的每一行對應於輸入句子中的一個單詞。(圖中的4個方框論文中為512個)和q / k / v向量(圖中的3個方框論文中為64個)

公式中濃縮前面步驟2到5來計算self attention層的輸出。

The Beast With Many Heads

使用“Multi-headed”的機制來進一步完善self-attention層。“Multi-headed”主要通過兩個方面改善了Attention層的性能,參數組成和子空間映射:

Many Heads的優缺點:

  • 它拓展了模型關注不同位置的能力。Multi head 的每個參數矩陣都會記錄單詞的位置信息,使原來的單個位置信息變得更加複雜。

  • 它為attention層提供了多個“representation subspaces”。由下圖可以看到,在self attention中,我們有多個個Query / Key / Value權重矩陣(Transformer使用8個attention heads),使特徵的提取變得更加複雜,而不是作為一個整體的特徵進行,每個單獨的子空間都會進行上下文的信息融合

在8個不同的子空間進行self-attention的操作,每個單詞生成獨立的8個向量

將8個子空間生成的向量壓縮成一個大向量,每個向量的子空間矩陣能夠學習到更多細節,壓縮過程採用一個更大的參數矩陣進行,對multi-head向量進行組合,生成最終的特徵向量。

整體的框圖來表示一下計算的過程:

Representing The Order of The Sequence Using Positional Encoding

其實上面介紹的網絡裏面並沒有考慮序列的位置信息,在RNN中不同時刻的信息是通過遞歸網絡的時間t來刻畫的,有明顯的時間刻度,所以引入了位置向量來解決時間刻度問題。

為了讓模型捕捉到單詞的順序信息,添加位置編碼向量信息(POSITIONAL ENCODING),位置編碼向量不需要訓練,它有一個規則的產生方式,生成與詞嵌入向量有着相同的向量就可以。

通過構造函數sin、cos來對位置進行嵌入,pos為單詞位置信息,而i用來表達dimension 這裏為了好說明,如果2i= dmodel, PE 的函數就是sin(pos/10000)。這樣的sin, cos的函數是可以通過線性關係互相表達的,通過兩個函數對奇偶維度進行編碼。位置編碼的公式如下圖所示:

個人認為選擇正餘弦函數主要是在-1和1之間是一個對稱關係,兩個相鄰的維度編碼相差比較大,在位置上有更好的區分性,1000是序列的長度,一般盡量將取值範圍控制在四分一個周期裏面,這樣會使每一個序列的每一個維度都取唯一的值。

The Residuals

編碼器和解碼器裏面的每一層都採用殘差的思想進行訓練,目的就是為了解決網絡過深情況下的難訓練問題,殘差連接可以將目標值問題轉化成零值問題,一定程度也可以減少網絡的過擬合問題。

使用殘差連接的編碼器內部結構:

使用殘差連接的編碼器-解碼器內部結構:

The Decoder Side

通過自回歸方式進行預測,解碼器每一個時間步輸入一個單詞,然後輸出一個單詞,將預測的單詞作為下一時刻的輸入進行單詞的預測,直到預測結束。

The Final Linear and Softmax Layer

  • 線性層是一個簡單的全連接神經網絡,模型一次生成一個輸出,我們可以假設模型從該概率分佈中選擇具有最高概率的單詞並丟棄其餘的單詞。

  • 對於最終句子的生成有2個方法:一個是貪婪算法(greedy decoding),一個是波束搜索(beam search)。

Bidirectional Encoder Representation from Transformers

Word Embedding

  • 線性模型,主要是對高維空間進行映射,其實是對one-hot向量的空間轉換。

  • 通過神經網絡對輸入的詞進行映射,獲取詞向量,一般有cbow和skip-gram兩種方法,此方法訓練的詞向量與上下文無關,並沒有參考位置信息,只是對詞的有無進行參考,採用的是負採樣,預測的時候進行的是一個二分類器,模型認為只要在下文中找出正確的詞就認為是完成了任務。

尚未解決一詞多義等問題。比如多義詞Bank,有兩個常用含義,但是Word Embedding在對bank這個單詞進行編碼的時候,是區分不開這兩個含義的,因為它們儘管上下文環境中出現的單詞不同,但是在用語言模型訓練的時候,不論什麼上下文的句子經過word2vec,都是預測相同的單詞bank,而同一個單詞占的是同一行的參數空間,這導致兩種不同的上下文信息都會編碼到相同的word embedding空間里去。所以word embedding無法區分多義詞的不同語義,這就是它的一個比較嚴重的問題。

Embedding from Language Models(ELMO)

  • ElMO採用雙向的LSTM做上下文相關的任務,從前到后和後到前分別做一遍LSTM的encoding操作,從而獲得兩個方向的token聯繫。

  • Word Embedding本質上是個靜態的方式,所謂靜態指的是訓練好之後每個單詞的表達就固定住了,以後使用的時候,不論新句子上下文單詞是什麼,這個單詞的Word Embedding不會跟着上下文場景的變化而改變,所以對於比如Bank這個詞,它事先學好的Word Embedding中混合了幾種語義 ,在應用中來了個新句子,即使從上下文中(比如句子包含money等詞)明顯可以看出它代表的是“銀行”的含義,但是對應的Word Embedding內容也不會變,它還是混合了多種語義。

ELMO的本質思想是:

事先用語言模型學好一個單詞的Word Embedding,此時多義詞無法區分,不過這沒關係。在我實際使用Word Embedding的時候,單詞已經具備了特定的上下文了,這個時候我可以根據上下文單詞的語義去調整單詞的Word Embedding表示,這樣經過調整后的Word Embedding更能表達在這個上下文中的具體含義,自然也就解決了多義詞的問題了。所以ELMO本身是個根據當前上下文對Word Embedding動態調整的思路。

一樣的,在具體進行下游任務的時候,採用神經網絡參數微調的方法根據不同的詞的上下文環境對詞向量進行調整,從而得到同一詞的不同向量表示。

缺點:

  • LSTM的抽取能力遠遠落後於Transformer,主要是并行計算能力

  • 拼接方式融合雙向特徵能力偏弱

Bidirectional Encoder Representation from Transformers

BRET採用兩階段模型,首先是語言模型預訓練;其次是使用Fine-Tuning模式解決下游任務。在預訓練階段採用了類似ELMO的雙向語言模型,雙向指的是對於預測單詞的上文和下文是否參与,如果都參与預測那麼就是雙向,雙向容易導致自己看自己的問題,後面提出mask來解決

經過預訓練的BRET模型,其已經具備了豐富的詞向量特徵信息,然後將此詞向量信息與下游任務進行組合進行NLP下游任務,例如文本生成,文本分類。

如何能夠更好將BRET模型與下游任務進行改造是一個比較複雜的問題,再好的預訓練語言模型都要與下游的任務模型相結合才有好的效果, BRET的優勢在於可以自由根據預訓練模型進行單詞級別的任務和句子級的任務。

BRET模型的創新

就是論文中指出的Masked 語言模型和Next Sentence Prediction。而Masked語言模型上面講了,本質思想其實是CBOW,但是細節方面有改進。

Masked 語言模型:

  • 而Masked語言模型上面講了,本質思想其實是CBOW,但是細節方面有改進,掩蓋的同時,要輸出掩蓋的詞的位置,然後用真實詞來預測。
  • Mask LM主要是為了增加模型的魯棒性和實際性能,但是在訓練時使用mask過多會影響實際任務的表現,所以做了一些處理:隨機選擇語料中15%的單詞,把它摳掉,也就是用[Mask]掩碼代替原始單詞,然後要求模型去正確預測被摳掉的單詞。但是這裡有個問題:訓練過程大量看到[mask]標記,但是真正後面用的時候是不會有這個標記的,這會引導模型認為輸出是針對[mask]這個標記的,但是實際使用又見不到這個標記,這自然會有問題。為了避免這個問題, BRET改造了一下,15%的被選中要執行[mask]替身這項光榮任務的單詞中,只有80%真正被替換成[mask]標記,10%被狸貓換太子隨機替換成另外一個單詞,10%情況這個單詞還待在原地不做改動。這就是Masked雙向語音模型的具體做法。

Next Sentence Prediction:

  • 指的是做語言模型預訓練的時候,分兩種情況選擇兩個句子,一種是選擇語料中真正順序相連的兩個句子;另外一種是第二個句子從語料庫中拋色子,隨機選擇一個拼到第一個句子後面。
  • 我們要求模型除了做上述的Masked語言模型任務外,附帶再做個句子關係預測,判斷第二個句子是不是真的是第一個句子的後續句子。之所以這麼做,是考慮到很多NLP任務是句子關係判斷任務,單詞預測粒度的訓練到不了句子關係這個層級,增加這個任務有助於下游句子關係判斷任務。所以可以看到,它的預訓練是個多任務過程。這也是BRET的一個創新,一般用於句級任務。

Transformer&BERT總結

  • 首先是兩階段模型,第一階段雙向語言模型預訓練,這裏注意要用雙向而不是單向,第二階段採用具體任務Fine-tuning或者做特徵集成;

  • 第二是特徵抽取要用Transformer作為特徵提取器而不是RNN或者CNN;

  • 第三,雙向語言模型可以採取CBOW的方法去做(當然我覺得這個是個細節問題,不算太關鍵,前兩個因素比較關鍵)。 BRET最大的亮點在於效果好及普適性強,幾乎所有NLP任務都可以套用BRET這種兩階段解決思路,而且效果應該會有明顯提升。可以預見的是,未來一段時間在NLP應用領域,Transformer將佔據主導地位,而且這種兩階段預訓練方法也會主導各種應用。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

分類
發燒車訊

談談 Promise 以及實現 Fetch 的思路

Promise 是異步編程的一種解決方案。

Promise


/**
 * 屬性
 */
Promise.length
Promise.prototype

/**
 * 方法
 */
Promise.all(iterable)   // 所有成功觸發成功  任何失敗觸發失敗
Promise.race(iterable)  // 任意一個成功或失敗后觸發
Promise.reject(reason)
Promise.resolve(value)

/**
 * 原型
 */
Promise.prototype.constructor
//方法
Promise.prototype.catch(onRejected)
Promise.prototype.then(onFulfilled, onRejected)
Promise.prototype.finally(onFinally)

Promise 有三種狀態

  • pending: 初始狀態,既不是成功,也不是失敗狀態。
  • resolve: 意味着操作成功完成。(resoloved)
  • reject: 意味着操作失敗。

pending

pending 是初始狀態,執行 resolve/reject 會進入對應狀態,如果不執行,責一直為 pending 狀態

例如下面代碼,promise 將一直在 pending 狀態,不會執行 then/catch.

new Promise(function (resolve, reject) { })
  .then(res => console.log(res))
  .catch(err => console.log(err))

resolve

resolve 意味着操作成功完成, 如果有 .then,值會傳入 .then 的第一個參數函數里。

new Promise(function (resolve, reject) {
  resolve(1)
})
  .then(res => console.log(res))

then 的第一個參數是成功的回調,第一個參數的返回值會影響接下來鏈的去向。第一個參數的返回值一般有三種情況

  • 無返回值:會去執行下一個 .then ,沒有參數
  • 返回值非promise:調用下一個then的函數,參數為返回值
  • 返回值為promise:根據promise的執行結果,執行 下一個then/catch,如果一直是pending,則不執行下一個then/catch

例如想要在當前 then 終止,可以這樣操作:

  .then((res) => new Promise(() => {}))

reject

reject 意味着操作失敗。

使用 .catch 會捕獲到錯誤信息。

與代碼報錯(如 undefined.a)不同的是, 代碼報錯如果不使用 catch 捕獲,會向外傳遞,最終傳遞到根結點;而 reject 屬於 promise 錯誤,即使不使用 catch 捕獲也不會對全局有影響。

用 promise 實現 fetch

先來看幾個問題:

  1. 如果請求 code 404, 會走 then 還是 catch? (答案:then)
  2. 控制台能看到一行 404 的錯誤, 為什麼還是走 then 不是 catch 呢
  3. 如果請求跨域失敗,走 then 還是 catch?(答案:catch)
  4. 同樣是控制台看到錯誤,兩者有什麼區別呢?
  5. 跨域失敗的報錯, 和 then 中 undefined.a 報錯,如果都不 catch,後者在 react 腳手架開發環境頁面會蹦,兩者有什麼區別?

帶着這幾個問題,來看看 fetch。

fetch 返回值是 promise,所以有三種狀態 pending、resolve、reject.

  • pending: 請求中
  • resolve: 請求成功(code 200/404/500 等, 非 200 控制台輸出錯誤)
  • reject: 請求失敗(跨域失敗、連接超時、無網絡等,控制台輸出錯誤)

我們還發現,請求失敗時,只能 catch 到最後一行錯誤, 如圖

捕獲后

為什麼 404 在控制台看到錯誤,還走 then, resolve 如何實現

實現有幾個難點,

  1. throw 後面代碼不會執行;
  2. 先報錯,后執行 then;
  3. catch 后錯誤不會打印在控制台;

試了下,Promise.reject(‘xxx’) 這樣的報錯方式雖然是微觀任務,但是總是在.then之後才在控制台輸出,更像是宏觀任務。所以也加個setTImeout宏觀任務調至後面。

var fetch = function () {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      if ('請求成功 200') {
        resolve('Response數據結構');
      } else if ('請求成功 404,500等') {
        Promise.reject('GET xxxxxxxx 404');
        setTimeout(function () {
          resolve('Response數據結構');
        });
      }
    })
  })
}

請求失敗 例如跨域失敗 reject 如何實現呢

同樣加個 setTimeout

var fetch = function () {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      if ('請求成功 200') {
        resolve('Response數據結構');
      } else if ('請求成功 404,500等') {
        Promise.reject('GET xxxxxxxx 404');
        setTimeout(function () {
          resolve('Response數據結構');
        });
      } else if ('請求失敗') {
        Promise.reject('Access to fetch xxxxx with CORS disabled.');
        Promise.reject('GET xxxxx net::ERR_FAILED');
        setTimeout(function () {
          reject('TypeError: Failed to fetch');
        });
      }
    })
  })
}

還是有些問題,我們實現的因為在promise 中,錯誤會有前綴 Uncaught (in promise)。瀏覽器客戶端應該有更好的實現方式。

最後總結一下 fetch 的三種情況

  • pending: 請求中
  • resolve: 請求成功(code 200: 調用 resolve 返回數據; code: 404/500 等, 先拋錯,再調用 resolve 返回數據。)
  • reject: 請求失敗(跨域失敗、連接超時、無網絡等,先控制台拋錯,再調用 reject)

拋錯均不影響代碼執行,與 undefined.a 不同。

whosmeya.com

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

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

分類
發燒車訊

2015年京津冀公共服務新能源車將達20222輛

22日,中國工信部、發改委及科技部等七部委聯合印發《京津冀公交等公共服務領域新能源汽車推廣工作方案》,提出2014年到2015年,京津冀地區公共交通服務領域共推廣20,222輛新能源汽車。其中北京市8,507輛,天津市6,000輛,河北省5,715輛,京津冀地區公交車中新能源汽車到2015年底比例不低於16%,京津出租車中新能源汽車比例不低於5%。   2014年到2015年,京津冀地區共新建充/換電站94座,充電樁新增1.62萬個。到2015年底,京津冀地區充換電站總數將達到112座,充電樁總數將達到19,657個,基本建成以保障運行為前提,建設規模適度超前的充電設施網絡。

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

【其他文章推薦】

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

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

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

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

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

※教你寫出一流的銷售文案?

分類
發燒車訊

新物種!泰國發現巨大「鯊齒龍」 位居食物鏈頂端

摘錄自2019年10月11日自由時報報導

由泰國、日本大學合力進行的研究,在泰國發現一種具有鯊狀齒的大型肉食性恐龍,長逾8公尺,是同一時期已知最大體型的掠食性恐龍。

這份研究由泰國NRRU大學及日本福井縣立大學的研究人員合作進行,9日發表於,研究人員表示,從泰國出土、帶有鯊魚狀牙齒的掠食性恐龍被證實是前所未見的新物種,生存於1.15億年前的下白堊紀,並獲命名為「Siamraptor suwati」。

研究報告指出,在這次考古研究中,科學家發現的化石至少來自4隻不同恐龍的個別部位,其中包括頭骨、齒骨、脊椎、尾部及四肢,推測其行進時以後二肢站立,前足則負責抓扣、撕扯。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

分類
發燒車訊

大數據:全球1/3碳排放 來自這20間公司

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

分類
發燒車訊

DNS篇(詳解DNS)

*文章來源:https://blog.egsec.cn/archives/601

*本文將主要說明:本文主要敘述什麼是DNS、域名的層級、DNS 解析過程、DNS的緩存時間、DNS 的記錄類型、DNS 報文結構、DNS劫持與HTTP劫持以及手動清理本地緩存的方法。

 

DNS屬於應用層。DNS即域名系統,其作用是將字符串域名解析成相對於的服務器IP地址,免除人們記憶IP地址的單調和苦惱,屬於為用戶排憂解難之舉,因此劃歸為應用層。DNS不屬於協議,它是域名解析。

 

什麼是DNS

DNS是 Domain Name System 的縮寫,也就是 域名解析系統,它的作用非常簡單,就是根據域名查出對應的 IP地址。

你可以把它想象成一本巨大的電話本,比如當你要訪問域名www.egsec.cn,首先要通過DNS查出它的IP地址是118.31.61.137。

域名層級

DNS 的解析過程中,需要對域名的層級有了解:

  • 根域名 :.root 或者 . ,通常是省略的
  • 頂級域名,如 .com,.cn 等
  • 次級域名,如 baidu.com 里的 baidu,這個是用戶可以進行註冊購買的
  • 主機域名,比如 baike.baidu.com 里的baike,這個是用戶可分配的 
主機名.次級域名.頂級域名.根域名
baike.baidu.com.root

DNS 解析過程

咱們以訪問 www.egsec.cn 這個域名為例,來看一看當你訪問 www.egsec.cn 時,會發生哪些事:

  1. 先查找本地 DNS 緩存(自己的電腦上),有則返回,沒有則進入下一步
  2. 查看本地 hosts 文件有沒有相應的映射記錄,有則返回,沒有則進入下一步
  3. 向本地 DNS 服務器(一般都是你的網絡接入服務器商提供,比如中國電信,中國移動)發送請求進行查詢,本地DNS服務器收到請求后,會先查下自己的緩存記錄,如果查到了直接返回就結束了,如果沒有查到,本地DNS服務器就會向DNS的根域名服務器發起查詢請求:請問老大, www.egsec.cn 的ip是啥?
  4. 根域名服務器收到請求后,看到這是個 .cn 的域名,就回信說:這個域名是由 .cn 老弟管理的,你去問他好了,這是.cn老弟的聯繫方式(ip1)。
  5. 本地 DNS 服務器接收到回信后,照着老大哥給的聯繫方式(ip1),馬上給 .cn 這個頂級域名服務器發起請求:請問 .cn 大大,www.egsec.cn 的ip 是啥?
  6. .cn 頂級域名服務器接收到請求后,看到這是 egsec.cn 的域名,就回信說:這個域名是 .egsec.cn 老弟管理的,你就去問他就行了,這是他的聯繫方式(ip2)
  7. 本地 DNS 服務器接收到回信后,按照前輩的指引(ip2),又向 .egsec.cn 這個權威域名服務器發起請求:請問 egsec.cn 大大,請問 www.egsec.cn 的ip是啥?
  8. egsec.cn 權威域名服務器接收到請求后,確認了是自己管理的域名,馬上查了下自己的小本本,把 www.egsec.cn 的ip告訴了 本地DNS服務器。
  9. 本地DNS服務器接收到回信后,非常地開心,這下總算拿到了www.egsec.cn的ip了,馬上把這個消息告訴了要求查詢的客戶(就是你的電腦)。由於這個過程比較漫長,本地DNS服務器為了節省時間,也為了盡量不去打擾各位老大哥,就把這個查詢結果偷偷地記在了自己的小本本上,方便下次有人來查詢時,可以快速回應。

總結起來就是三句話:

  • 從”根域名服務器”查到”頂級域名服務器”的NS記錄和A記錄(IP地址)
  • 從”頂級域名服務器”查到”次級域名服務器”的NS記錄和A記錄(IP地址)
  • 從”次級域名服務器”查出”主機名”的IP地址

DNS的緩存時間

上面的幾個步驟里,可以看到有兩個地方會緩存 DNS 的查詢記錄,有了緩存,在一定程度上會提高查詢效率,但同時在準確率上會有所損失。

因此我們在配置 DNS 解析的時候,會有一個 TTL 參數(Time To Live),意思就是這個緩存可以存活多長時間,過了這個時間,本地 DNS 就會刪除這條記錄,刪除了緩存后,你再訪問,就要重新走一遍上面的流程,獲取最新的地址。

DNS 的記錄類型

當我們在阿里雲買了一個域名后,可以配置我們主機域名解析規則,也就是 記錄。  

阿里雲域名雲解析(不管是哪個服務商都一樣):

常見的 DNS 記錄類型如下

  • A:地址記錄(Address),返回域名指向的IP地址。
  • NS:域名服務器記錄(Name Server),返回保存下一級域名信息的服務器地址。該記錄只能設置為域名,不能設置為IP地址。
  • MX:郵件記錄(Mail eXchange),返回接收电子郵件的服務器地址。
  • CNAME:規範名稱記錄(Canonical Name),返回另一個域名,即當前查詢的域名是另一個域名的跳轉,詳見下文。
  • PTR:逆向查詢記錄(Pointer Record),只用於從IP地址查詢域名,詳見下文。

DNS報文結構

  1. 事務 ID:DNS 報文的 ID 標識。對於請求報文和其對應的應答報文,該字段的值是相同的。通過它可以區分 DNS 應答報文是對哪個請求進行響應的。
  2. 標誌:DNS 報文中的標誌字段。
  3. 問題計數:DNS 查詢請求的數目。
  4. 回答資源記錄數:DNS 響應的數目。
  5. 權威名稱服務器計數:權威名稱服務器的數目。
  6. 附加資源記錄數:額外的記錄數目(權威名稱服務器對應 IP 地址的數目)

DNS劫持與HTTP劫持

通過上面的講解,我們都知道了,DNS 完成了一次域名到 IP 的映射查詢,當你在訪問 www.egsec.cn 時,能正確返回給你 我網站首頁的 ip。

但如果此時 DNS 解析出現了一些問題,當你想要訪問 www.egsec.cn 時,卻返回給你 www.baidu.com 的ip,這就是我們常說的 DNS 劫持。

與之容易混淆的有 HTTP 劫持。

什麼是 HTTP 劫持?

你一定見過當你在訪問 某個網站時,右下角也突然彈出了一個扎眼的廣告彈窗。這就是 HTTP 劫持。

藉助別人文章里的例子,它們倆的區別就好比是

  • DNS劫持是你想去機場的時候,把你給丟到火車站。
  • HTTP劫持是你去機場途中,有人給你塞小廣告。

DNS劫持 是如何產生的?

下面大概說幾種DNS劫持方法:

1.本機DNS劫持

攻擊者通過某些手段使用戶的計算機感染上木馬病毒,或者惡意軟件之後,惡意修改本地DNS配置,比如修改本地hosts文件,緩存等

2. 路由DNS劫持

很多用戶默認路由器的默認密碼,攻擊者可以侵入到路由管理員賬號中,修改路由器的默認配置

3.攻擊DNS服務器

直接攻擊DNS服務器,例如對DNS服務器進行DDOS攻擊,可以是DNS服務器宕機,出現異常請求,還可以利用某些手段感染dns服務器的緩存,使給用戶返回來的是惡意的ip地址

如何在本地查詢 DNS 解析結果?

nslookup命令:

命令格式:nslookup [查詢的域名] [指定DNS服務器]

你也可以指定公網的域名服務器進行查詢,比如常見的 114.114.114.114

手動清理DNS緩存

MacOS:

sudo dscacheutil -flushcache
$ sudo killall -HUP mDNSResponder

Windows:

$ ipconfig /flushdns

Linux:

使用NSCD的DNS緩存
$ sudo /etc/init.d/nscd restart

# 服務器或者路由器使用DNSMASQ
$ sudo dnsmasq restart

  

DNS詳解篇完

轉發請註明出處(EG Blog:blog.egsec.cn),謝謝!

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

※教你寫出一流的銷售文案?