Ⅰ promise 風格編程書寫格式詳解
我們在使用 promise 的時候,會寫出許多有問題的 promise 代碼。 當然並不是 promise 本身的問題,A+ spec 規范定義的 promise 非常棒。 在過去的幾年中,筆者看到了很多程序員在調用 PouchDB 或者其他 promise 化的 API 時遇到了很多困難。這讓筆者認識到,在 JavaScript 程序員之中,只有少數人是真正理解了 promise 規范的。如果這個事實讓你難以接受,那麼思考一下我在 Twitter 上出的題:
問:下面四個使用 promise 的語句之間的不同點在哪兒?
doSomething().then(function () {
return doSomethingElse();
});
doSomethin().then(functiuoin () {
doSomethingElse();
});
doSomething().then(doSomethingElse());
doSomething().then(doSomethingElse);
如果你知道這個問題的答案,那麼恭喜你,你已經是一個 promise 大師並且可以直接關閉這個網頁了。
但是對於不能回答這個問題的程序員中 99.9% 的人,別擔心,你們不是少數派。沒有人能夠在筆者的 tweet 上完全正確的回答這個問題,而且對於 #3 最終答案也令我感到震驚,即便我是出題人。
答案在本文的底部,但是首先,筆者必須先探究一下 promise 為何如此復雜,為什麼不管是新手還是專家都有被 promise 折磨的經歷。同時,筆者也會給出自認為能夠快速、准確理解 promise 的方法。而且筆者確信讀過這篇文章之後,理解 promise 不會那麼難了。
Ⅱ 關於generator非同步編程的理解以及如何動手寫
關於generator非同步編程的理解以及如何動手寫一個co模塊
generator出現之前,想要實現對非同步隊列中任務的流程式控制制,大概有這么一下幾種方式:
回調函數
事件監聽
發布/訂閱
promise對象
第一種方式想必大家是最常見的,其代碼組織方式如下:
我們把函數放到run的執行器裡面,便實現了同步操作非同步代碼的過程
Ⅲ JS的Promise兄弟
相信用過JS的都知道JS是單線程的,同步的函數先執行,非同步的函數先加入到一個隊列中等同步執行完了再執行非同步函數。基於這個JS採用非同步回調的方式來處理需要等待的事件,是的代碼會繼續執行而不用在非同步處理的地方一直等待著。同時也帶來一個不好的方面,如果我們有很多的回調函數, 也就是說一個回調函數里邊再嵌套一個回調一層一層的嵌套,這樣就很容易進入傳說中的回調地獄。
注意:非同步和回調不是一個東西
下面感受一下回調地獄代碼的魅力:
是挺有美感的但是閱讀性很差,寫法也讓人感到無力,es6新出的promise對象已經es7的async await都可以解決這個問題,但是今天的主角是Promise。
Promise是非同步編程的一種解決方案,可以替代傳統的解決方案--回調函數和事件。ES6統一了用法,並原生提供了Promise對象。作為對象,Promise有一下兩個特點:(1)對象的狀態不受外界影響;(2)一旦狀態改變了就不會在變,也就是說任何時候Promise都只有一種狀態。Promise有三種狀態,分別是:Pending(進行中),Resolved(完成),Rejected (失敗)。Promise從Pending狀態開始,如果成功就轉到成功態,並執行resolve回調函數;如果失敗就轉到失敗狀態並執行reject回調函數。
Promise一旦狀態改變,就不會再變,任何時候都可以得到這個結果。Promise 對象的狀態改變,只有兩種可能:從 Pending 變為 Resolved 和從 Pending 變為 Rejected。只要這兩種情況發生,狀態就凝固了,不會再變了,會一直保持這個結果。就算改變已經發生了,你再對 Promise 對象添加回調函數,也會立即得到這個結果。這與事件(Event)完全不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的。
Promise構造函數接收一個函數作為參數,該函數的兩個參數是resolve,reject,它們由JavaScript引擎提供。其中resolve函數的作用是當Promise對象轉移到成功,調用resolve並將操作結果作為其參數傳遞出去;reject函數的作用是單Promise對象的狀態變為失敗時,將操作報出的錯誤作為其參數傳遞出去
介紹一下Promise的api怎麼使用:
1、Promise.resolve()的作用將現有對象轉為Promise對象resolved;Promise.resolve('test')==new Promise(resolve=>resolve('test'))
2、Promise.reject()返回一個Promise對象,狀態為rejected
3、Promise.prototype.then()方法接受兩個參數,第一個是成功的resolved的回調,另一個是失敗rejected的回調,第二個失敗的回調參數可選。並且then方法里也可以返回promise對象,這樣就可以鏈式調用了。
4、Promise.prototype.catch()發生錯誤的回調函數。
5、Promise.all() // 所有的事都有完成,相當於 且,適合用於所有的結果都完成了才去執行then()成功的操作。
6、Promise.race() // 完成一個任務即可,相當於 或。(這個經常用在一些圖片比較多的網站)
Ⅳ promise的三種狀態
promise的三種狀態
Promise 是非同步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。它由社區最早提出和實現,ES6將其寫進了語言標准,統一了用法,原生提供了Promise對象。
所謂Promise,簡單說就是一個容器,裡面保存著某個未來才會結束的事件(通常是一個非同步操作)的結果。從語法上說,Promise 是一個對象,從它可以獲取非同步操作的消息。Promise 提供統一的 API,各種非同步操作都可以用同樣的方法進行處理。
Promise對象有以下兩個特點。
(1)對象的狀態不受外界影響。Promise對象代表一個非同步操作,有三種狀態:Pending(進行中)、Resolved(已完成,又稱 Fulfilled)和Rejected(已失敗)。只有非同步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。這也是Promise這個名字的由來,它的英語意思就是「承諾」,表示其他手段無法改變。
(2)一旦狀態改變,就不會再變,任何時候都可以得到這個結果。Promise對象的狀態改變,只有兩種可能:從Pending變為Resolved和從Pending變為Rejected。只要這兩種情況發生,狀態就凝固了,不會再變了,會一直保持這個結果。如果改變已經發生了,你再對Promise對象添加回調函數,也會立即得到這個結果。這與事件(Event)完全不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的。
有了Promise對象,就可以將非同步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數。此外,Promise對象提供統一的介面,使得控制非同步操作更加容易。
Promise也有一些缺點。首先,無法取消Promise,一旦新建它就會立即執行,無法中途取消。其次,如果不設置回調函數,Promise內部拋出的錯誤,不會反應到外部。第三,當處於Pending狀態時,無法得知目前進展到哪一個階段(剛剛開始還是即將完成)。
如果某些事件不斷地反復發生,一般來說,使用 Stream 模式是比部署Promise更好的選擇。
Ⅳ 前端的Promise是幹啥的
Promise是非同步編程的一種解決方案,可以替代傳統的解決方案--回調函數和事件。ES6統一了用法,並原生提供了Promise對象。作為對象,Promise有以下兩個特點:
(1)對象的狀態不受外界影響。
(2)一旦狀態改變了就不會在變,也就是說任何時候Promise都只有一種狀態。
可以通過Promise的構造函數創建Promise對象。
varpromise=newPromise(function(resolve,reject)setTimeout(function(){
console.log("helloworld");},2000);
});
Promise構造函數接收一個函數作為參數,該函數的兩個參數是resolve,reject,它們由JavaScript引擎提供。其中resolve函數的作用是當Promise對象轉移到成功,調用resolve並將操作結果作為其參數傳遞出去;reject函數的作用是單Promise對象的狀態變為失敗時,將操作報出的錯誤作為其參數傳遞出去。如下面的代碼:
functiongreet(){varpromise=newPromise(function(resolve,reject){vargreet="helloworld";
resolve(greet);
});returnpromise;
}
greet().then(v=>{console.log(v);//*
})
上面的*行的輸出結果就是greet的值,也就是resolve()傳遞出來的參數。
注意:創建一個Promise對象會立即執行裡面的代碼,所以為了更好的控制代碼的運行時刻,可以將其包含在一個函數中,並將這個Promise作為函數的返回值。
Promise的then方法
promise的then方法帶有以下三個參數:成功回調,失敗回調,前進回調,一般情況下只需要實現第一個,後面是可選的。Promise中最為重要的是狀態,通過then的狀態傳遞可以實現回調函數鏈式操作的實現。先執行以下代碼:
functiongreet(){varpromise=newPromise(function(resolve,reject){vargreet="helloworld";
resolve(greet);
});returnpromise;
}varp=greet().then(v=>{console.log(v);
})console.log(p);