奇葩!面試說真話居然也能拿offer?

小白沖沖沖沖 發佈 2020-01-07T06:21:24+00:00

今年的快結束了,小張海投了一波簡歷,幾經面試無果,終於又收到了一家面試通知,急急忙忙趕到了面試地點…-----面試現場-----程式設計師小張:你好,我是來面試的面試官:你好,這是你面試的第一家公司嗎?程式設計師小張:當然不是啦,面了30多家,都不要我。

今年的快結束了,小張海投了一波簡歷,幾經面試無果,終於又收到了一家面試通知,急急忙忙趕到了面試地點…

-----面試現場-----

程式設計師小張:你好,我是來面試的

面試官:你好,這是你面試的第一家公司嗎?

程式設計師小張:當然不是啦,面了30多家,都不要我。

面試官:哦哦哦,沒事,我們面試了50多個,1個都不願意來呢。

你簡歷上寫的5年前端開發經驗…

程式設計師小張:大學編程設計也算進去了,全靠同學我划水!實際上工作不到3年…

面試官:曾參與主導十萬級以上用戶的中大型項目研發…

程式設計師小張:之前公司負責一個政府外包項目,我提了一丁點兒意見…

面試官:精通javascript/Node, 熟練掌握原生js,css3,es6,響應式布局等, 熟悉常用

設計模式,┅┅混合app,小程序等開發部署,熟悉webpack,cdn打包性能優化

程式設計師小張:都是吹的,知道一點兒,就是會寫寫點頁面,會點Ajax請求!

面試官:那就好!嚇我一跳,這些你要是都精通,我們肯定要不起!

我們公司最近打算做個電商app項目,類似淘寶那種,那你就講講具體的實現方式吧。

程式設計師小張:先搭建開發環境,再到模塊的設計和開發,組件封裝,訪問權限管理,數據請求交互優化,前端性能調優,,es6/7主流知識點的運用,再到打包部署,這些我雖然沒用過,但是都聽過!工作中一邊百度,一邊Google,大都可以解決的!

面試官:外瑞外瑞good啊!!!那談談薪資,你期望薪資是多少?

程式設計師小張:我期望薪資寫的25K,但7K也可以干,就是會偷懶。錢多點,幹活

就勤快點!

面試官:Hmmm,我們寫的是15~30K,實際上最多只給到10K,既然你水平有

限,那我就大方點給到8K!但是要經常加班哦!

程式設計師小張:可以的!反正加班我也是摸魚!

面試官:行吧,那明天來上班吧!

最近面試碰到是否理解promise和Async,具體怎麼用?運用場景?一起學習下:

一、Promise

凡事有因必有果,新事物的出現就代表著老的事物不能滿足我們的需求了。Promise 這個新事物就是在這個背景下出現的,而它代替的老事物就是ES6 之前經常被用的 callback(回調函數)。

1)、回調地獄

什麼是回調地獄?

一般來說回調地獄就是出現在異步操作中,下一次的操作依賴上一次的結果,一環套一環,套著套著就套的我們頭痛難忍,寫出了上面的代碼。我自己是一名從事了多年開發的web前端老程式設計師,目前辭職在做自己的web前端私人定製課程,今年年初我花了一個月整理了一份最適合2019年學習的web前端學習乾貨,各種框架都有整理,送給每一位前端小夥伴,想要獲取的可以關注我的頭條號並在後台私信我:前端,即可免費獲取。

雖說上面的這種情況不會真實的出現在項目中,但實際開發中為了拿到數據調用多個接口的情況是很常見的,比如要獲取圖片的路徑,需要先發送第一個請求,拿到圖片的ID,然通過圖片的ID拿到圖片的URL,這樣第二個請求需要在第一個請求完成後執行;

2)、Promise 解決異步避免回調地獄

Promise 的出現解決了這個問題,先來看看 Promise 怎麼解決回調地獄的。

3)、Promise 基礎

Promise 對象用於表示一個異步操作的最終完成 (或失敗),及其結果值。Promise 對象是一個代理對象(代理一個值),被代理的值在 Promise 對象創建時可能是未知的。它允許你為異步操作的成功和失敗分別綁定相應的處理方法(handlers)。這讓異步方法可以像同步方法那樣返回值,但並不是立即返回最終執行結果,而是一個能代表未來出現的結果的 promise 對象。

4)、Promise 狀態

一個 Promise 對象值是未知的,狀態是可變的,但是無論怎麼變化,它的狀態永遠處於以下三種之間:

· pending:初始狀態,既不是成功,也不是失敗。

· fulfilled:意味著操作成功完成。

· rejected:意味著操作失敗。

Promise 的狀態會發生變化,成功時會從pending -> fulfilled,失敗時會從pending -> rejected,但是此過程是不可逆的,也就是不能從另外兩個狀態變成pending。fulfilled/rejected這兩個狀態也被稱為 settled 狀態。

5)、Promise使用

JS 萬物皆對象,所以 Promise 也可以被我們new出來。我們通過下面的語法來新建一個 Promise 對象:

new Promise( function(resolve, reject) {...} /* executor */ );

Promise 的構造函數有一個參數 —— 是一個帶有兩個參數(resolve, reject)的函數,這兩個參數分別代表此次異步操作的結果也就是Promise的狀態。resolve和reject函數被調用時,分別會將此次 Promise 的狀態改成fulfilled或者rejected,一旦異步操作結束,Promise 的最終狀態只能是二者之一,如果異步成功,該狀態會被resolve函數修改為fullfilled;相反當異步過程中拋出一個錯誤,那麼該狀態就會被reject函數改成rejected。

6)、Promise API

Promise 的原型鏈以及對象本身有一些方法供我們使用,其中最常用也比較有可說性的就是下面這幾個:

then —— Promise.prototype.then(onFulfilled, onRejected)

添加解決(fulfillment)和拒絕(rejection)回調到當前 promise, 返回一個新的 promise, 將以回調的返回值來 resolve。

可以看到,.then裡面拿到的是我們 Promise resolve 過後的數據。並且他還會返回一個 Promise 繼續供我們調用,比如:

then()用法比較簡單,大家肯定也經常用,這裡其實就知道.then()是可以一直鏈式調用的,因為它的返回值也是一個 Promise,就可以了。

catch -- Promise.prototype.catch(onRejected)

添加一個拒絕(rejection) 回調到當前 promise, 返回一個新的 promise。當這個回調函數被調用,新 promise 將以它的返回值來 resolve,否則如果當前 promise 進入 fulfilled 狀態,則以當前 promise 的完成結果作為新 promise 的完成結果。

all —— Promise.all(iterable)

這個方法返回一個新的 promise 對象,該 promise 對象在 iterable 參數對象里所有的 promise 對象都成功的時候才會觸發成功,一旦有任何一個 iterable 裡面的 promise 對象失敗則立即觸發該 promise 對象的失敗。這個新的 promise 對象在觸發成功狀態以後,會把一個包含 iterable 里所有 promise 返回值的數組作為成功回調的返回值,順序跟 iterable 的順序保持一致;如果這個新的 promise 對象觸發了失敗狀態,它會把 iterable 里第一個觸發失敗的 promise 對象的錯誤信息作為它的失敗錯誤信息。Promise.all 方法常被用於處理多 個promise 對象的狀態集合。

這個算是我經常使用的一個 API 了,上面的內容雖然有點長,但是總結起來其實也很簡單,大概就是如下三個方面:

第一:接收一個 Promise 對象數組作為參數

第二:參數所有回調成功才是成功,返回值數組與參數順序一致

第三:參數數組其中一個失敗,則觸發失敗狀態,第一個觸發失敗的 Promise 錯誤信息作為 Promise.all 的錯誤信息。

Promise.all 用來處理多個並發請求,也是為了頁面數據構造的方便,將一個頁面所用到的在不同接口的數據一起請求過來,不過,如果其中一個接口失敗了,多個請求也就失敗了,頁面可能啥也出不來;

常見問題

setTimeout 和 Promise 都是異步操作,那麼誰更快呢?

總結:promise 無關順序更快執行

二、Async/Await

還得再來一遍,新事物的出現就代表著老的事物不能滿足我們的需求,ES6 剛出 Promise 來解決異步問題,ES7 就又出了一個 Async/Await(其實官方名字是 async function),看來 Promise 並沒有達到大傢伙的預期,所以官方就又搞了個更為優雅的異步解決方案。

為什麼說它是為了解決 Promise 帶來的問題,可以看看 MDN 官網的下面這段話:

async/await 的目的是簡化使用多個 promise 時的同步行為,並對一組 Promises 執行某些操作。正如 Promises 類似於結構化回調,async/await 更像結合了 generators 和 promises。

1)、Promise 並不是完美的解決方案

上面提到的那個異步嵌套 setTimeout的例子來說,事實上,大部分人用 Promise 應該並不會像上面的代碼那樣寫,而是下面這樣:

其實 Promise.then() 如果使用過多,依然還是回調地獄,嵌套依然沒有消失,所以來說,Promise 並不能稱之為完美的異步方案,ES7 提出了 async function,它用來更為優雅的解決異步

2)、async function 理解

關於 async function,其實並沒有過多的 API,因為它更像是一個高級語法糖,官方文檔給出的也更多都是使用示例。在這裡,其實我們只需要知道並強調一件事 —— await 關鍵字用來暫停等待異步函數的執行結束,如果是 Promise,也就是等待它的 settled 狀態,並且 await 只能出現在 async function 內部,不可單獨使用。

官方給出了一個比較有意思的例子:

第二種沒什麼可說的,想像中就是這個樣子,因為 await 會暫停等待函數執行完之後再向下執行,因此等待時間不會重疊,先等待2秒執行 slow 後再等待1秒執行 fast。

而第一種

上面這兩個異步函數因為沒有 await 關鍵字,都是立即執行,因此先輸出promise start,之後,兩個函數延時不同,雖然 slow 先執行,但是是2秒,而 fast 後執行是1秒,先輸出fast done再輸出slow done。最後,await 關鍵字發揮作用,雖然 fast 先執行完,但是你還是要等 await slow 完事之後才能 await fast。


作者:web小猿
連結:https://www.jianshu.com/p/7bae6711a906

關鍵字: