中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

做電影網(wǎng)站用什么空間怎樣做好網(wǎng)絡營銷推廣

做電影網(wǎng)站用什么空間,怎樣做好網(wǎng)絡營銷推廣,云南網(wǎng)站建設一度科技公司,巨騰外貿(mào)網(wǎng)站建設目錄 什么是 Promise 實現(xiàn)一個 Promise Promise 的聲明 解決基本狀態(tài) 添加 then 方法 解決異步實現(xiàn) 解決鏈式調(diào)用 完成 resolvePromise 函數(shù) 解決其他問題 添加 catch 方法 添加 finally 方法 添加 resolve、reject、race、all 等方法 如何驗證我們的 Promise 是否…

目錄

什么是 Promise

實現(xiàn)一個 Promise

Promise 的聲明

解決基本狀態(tài)

添加 then 方法

解決異步實現(xiàn)

解決鏈式調(diào)用

完成 resolvePromise 函數(shù)

解決其他問題

添加 catch 方法

添加 finally 方法

添加 resolve、reject、race、all 等方法

如何驗證我們的 Promise 是否正確?


什么是 Promise

Promise 是一種異步編程的解決方案。在異步操作中,callback 會導致回調(diào)地獄的問題,Promise 解決了這個問題。

一個 Promise對象有以下三種狀態(tài):

  • pending:初始狀態(tài),既不是成功,也不是失敗狀態(tài)。
  • fulfilled(resolved):意味著操作成功完成。
  • rejected:意味著操作失敗。

Promise對象內(nèi)部運行的一個變化, 變化如下:

  1. 當 new Promise() 被實例化后,即表示 Promise 進入 pending 初始化狀態(tài),準備就緒,等待運行。
  2. 一旦 Promise 實例運行成功或者失敗之后,實例狀態(tài)就會變?yōu)?fulfilled 或者 rejected,此時狀態(tài)就無法變更。

在使用 Promise 時,通常會調(diào)用其 then() 方法來處理異步操作的結果,或者調(diào)用 catch() 方法來處理出錯信息。同時,Promise 還提供了一些靜態(tài)方法,如 Promise.resolve()、Promise.reject() 等用于快速創(chuàng)建一個 Promise 實例。

實現(xiàn)一個 Promise

(下文所指的規(guī)定是指?Promise A+規(guī)范

Promise 的聲明

首先呢,promise 肯定是一個類,我們就用 class 來聲明。

  • 由于 new Promise((resolve, reject)=>{}) ,所以傳入一個參數(shù)(函數(shù) executor),傳入就執(zhí)行
  • executor 里面有兩個參數(shù),一個叫 resolve(成功),一個叫 reject(失敗)
  • 由于 resolve 和 reject 可執(zhí)行,所以都是函數(shù),我們用 let 聲明
class myPromise{// 構造器constructor(executor){// 成功let resolve = () => { };// 失敗let reject = () => { };// 立即執(zhí)行executor(resolve, reject);}
}
解決基本狀態(tài)

Promise 有規(guī)定:

  • Promise 存在三個狀態(tài)(state)pending、fulfilled、rejected
  • pending(等待態(tài))為初始態(tài),并可以轉化為 fulfilled(成功態(tài))和 rejected(失敗態(tài))
  • 成功時,不可轉為其他狀態(tài),且必須有一個不可改變的值(value)
  • 失敗時,不可轉為其他狀態(tài),且必須有一個不可改變的原因(reason)
  • new Promise((resolve, reject)=>{resolve(value)}) resolve 為成功,接收參數(shù) value,狀態(tài)改變?yōu)?fulfilled,不可再次改變。
  • new Promise((resolve, reject)=>{reject(reason)}) reject 為失敗,接收參數(shù) reason,狀態(tài)改變?yōu)?rejected,不可再次改變。
  • 若是 executor 函數(shù)報錯 直接執(zhí)行 reject();

于是乎,我們獲得以下代碼

class myPromise {constructor(executor) {// 初始化 state 為等待態(tài)this.state = 'pending'// 成功的值this.value = undefined// 失敗的原因this.reason = undefinedlet resolve = value => {// state 改變 resolve 調(diào)用就會失敗if (this.state === 'pending') {// resolve 調(diào)用后 state 轉化為成功態(tài)this.state = 'fulfilled'}// 儲存成功的值this.value = value}let reject = reason => {// state 改變 reject 調(diào)用就會失敗if (this.state === 'pending') {// reject 調(diào)用后 state 轉化為失敗態(tài)this.state = 'rejected'}// 儲存失敗的原因this.reason = reason}// 立即執(zhí)行 executor,如果 executor 執(zhí)行報錯,直接執(zhí)行 rejecttry {executor(resolve, reject)} catch(err) {reject(err)}}
}
添加 then 方法

Promise 有一個叫做 then 的方法,里面有兩個參數(shù):onFulfilled 和 onRejected,成功有成功的值,失敗有失敗的原因

  • 當狀態(tài) state 為 fulfilled,則執(zhí)行 onFulfilled,傳入 this.value。
  • 當狀態(tài) state 為 rejected,則執(zhí)行 onRejected,傳入 this.reason
  • onFulfilled 和 onRejected 如果是函數(shù),則必須分別在 fulfilled,rejected 后被調(diào)用,value 或reason 依次作為他們的第一個參數(shù)
class myPromise {constructor(executor){...}// then 方法有兩個參數(shù) onFulfilled 和 onRejectedthen(onFulfilled, onRejected) {// 狀態(tài)為 fulfilled,執(zhí)行 onFulfilled,傳入成功的值if (this.state === 'fulfilled') {onFulfilled(this.value)}// 狀態(tài)為 rejected,執(zhí)行 onRejected,傳入失敗的原因if (this.state === 'rejected') {onRejected(this.reason)}}
}
解決異步實現(xiàn)

現(xiàn)在基本可以實現(xiàn)簡單的同步代碼,但是當 resolve 在 setTomeout 內(nèi)執(zhí)行,調(diào)用 then 時 state 還是 pending 等待態(tài),我們就需要在 then 調(diào)用的時候,將成功和失敗存到各自的數(shù)組,一旦 reject 或者 resolve,就調(diào)用它們

類似于發(fā)布訂閱,先將 then 里面的兩個函數(shù)儲存起來,由于一個 promise 可以有多個 then,所以存在同一個數(shù)組內(nèi)。

// 多個 then 的情況
let p = new Promise();
p.then();
p.then();

成功或者失敗時,forEach 調(diào)用它們

class myPromise {constructor(executor) {this.state = 'pending'this.value = undefinedthis.reason = undefined// 成功存放的數(shù)組this.onResolvedCallbacks = []// 失敗存放的數(shù)組this.onRejectedCallbacks = []let resolve = value => {if (this.state === 'pending') {this.state = 'fulfilled'}this.value = value// 一旦 resolve 執(zhí)行,調(diào)用成功數(shù)組的函數(shù)this.onResolvedCallbacks.forEach(fn => fn());}let reject = reason => {if (this.state === 'pending') {this.state = 'rejected'}this.reason = reason// 一旦 reject 執(zhí)行,調(diào)用失敗數(shù)組的函數(shù)this.onRejectedCallbacks.forEach(fn => fn())}try {executor(resolve, reject)} catch(err) {reject(err)}}then(onFulfilled, onRejected) {if (this.state === 'fulfilled') {onFulfilled(this.value)}if (this.state === 'rejected') {onRejected(this.reason)}// 狀態(tài)為 pending 時if (this.state === 'pending') {// onFulfilled 傳入到成功數(shù)組this.onResolvedCallbacks.push(() => onFulfilled(this.value))// onRejected 傳入到失敗數(shù)組this.onRejectedCallbacks.push(() => onRejected(this.reason))}}
}
解決鏈式調(diào)用

我門常常用到 new Promise().then().then(),這就是鏈式調(diào)用,用來解決回調(diào)地獄

  1. 為了達成鏈式,我們默認在第一個 then 里返回一個 promise。規(guī)定了一種方法,就是在then 里面返回一個新的 promise 稱為 promise2
    let promise2 = new Promise((resolve, reject)=>{})
    1. 將這個 promise2 返回的值傳遞到下一個 then 中
    2. 如果返回一個普通的值,則將普通的值傳遞給下一個 then 中
  2. 當我們在第一個 then 中 return 了一個參數(shù)(參數(shù)未知,需判斷)。這個 return 出來的新的promise 就是 onFulfilled() 或 onRejected() 的值

規(guī)定 onFulfilled() 或 onRejected() 的值,即第一個 then 返回的值,叫做 x,判斷 x 的函數(shù)叫做 resolvePromise

class myPromise {constructor(executor){...}then(onFulfilled, onRejected) {   // 聲明返回的 promise2let promise2 = new myPromise((resolve, reject) => {if (this.state === 'fulfilled') {let x = onFulfilled(this.value)resolvePromise(promise2, x, resolve, reject)}if (this.state === 'rejected') {let x = onRejected(this.reason)resolvePromise(promise2, x, resolve, reject)}if (this.state === 'pending') {this.onResolvedCallbacks.push(() => {let x = onFulfilled(this.value)resolvePromise(promise2, x, resolve, reject)})this.onRejectedCallbacks.push(() => {let x = onRejected(this.reason)resolvePromise(promise2, x, resolve, reject)})}})// 返回 Promise,完成鏈式return promise2}
}
完成 resolvePromise 函數(shù)

規(guī)定了一段代碼,讓不同的 promise 代碼互相套用,叫做 resolvePromise

  • 如果 x === promise2,會造成循環(huán)引用,自己等待自己完成,則報“循環(huán)引用”錯誤
    let p = new Promise(resolve => {resolve(0);
    });
    var p2 = p.then(data => {// 循環(huán)引用,自己等待自己完成,一輩子完不成return p2;
    })
    
  • x 不能是 null
  • x 是普通值,直接 resolve(x)
  • x 是對象或者函數(shù)(默認 promise),?let then = x.then
  • 如果取 then 報錯,則走 reject()
  • 如果 then 是個函數(shù),則用 call 執(zhí)行 then,第一個參數(shù)是 x,后面是成功的回調(diào)和失敗的回調(diào)
  • 如果成功的回調(diào)還是 pormise,就遞歸繼續(xù)解析
  • 因為成功和失敗只能調(diào)用一個,所以設定一個 called 來防止多次調(diào)用
// 處理 x 的值,如果是普通值直接返回,如果是 promise 則返回 x.then 執(zhí)行的結果
function resolvePromise(promise2, x, resolve, reject) {// 如果 new 出來的 Promise2 和 x 是同一個,循環(huán)引用報錯if (promise2 === x) return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));// 先判斷是不是對象或者函數(shù)if (x !== null && (typeof x === 'object' || typeof x === 'function')) {// 調(diào)用了成功就不能失敗,調(diào)用了失敗就不能成功,不能多次調(diào)用成功或者失敗let called// 內(nèi)部可能拋出錯誤try {// 聲明 then = x 的 then 方法let then = x.then// 如果 then 是函數(shù),就默認是 promise 了if (typeof then === 'function') {this.call(x, res => {// 成功和失敗只能調(diào)用一個if (called) returncalled = true// res 可能是一個 promise,遞歸調(diào)用 resolvePromise,直到解析出的值是普通值resolvePromise(promise2, res, resolve, reject)}, err => {// 成功和失敗只能調(diào)用一個if (called) returncalled = true// 直接調(diào)用 reject 作為失敗的結果,并向下傳遞reject(err)})} else {// 如果 then 不是函數(shù),就說明是個普通值,直接返回 xresolve(x)}} catch(err) {// 也屬于失敗,成功和失敗只能調(diào)用一個if (called) returncalled = true// 直接調(diào)用 reject 作為失敗的結果,并向下傳遞reject(err)}} else {// x 是普通值,直接返回resolve(x)}
}
解決其他問題
  • 規(guī)定 onFulfilled 和 onRejected 都是可選參數(shù),如果他們不是函數(shù),必須被忽略
  • onFulfilled 返回一個普通的值,成功時直接等于 value => value
  • onRejected 返回一個普通的值,失敗時如果直接等于 value => value,則會跑到下一個 then 中的 onFulfilled 中,所以直接扔出一個錯誤 reason => throw err
  • 規(guī)定 onFulfilled 或 onRejected 不能同步被調(diào)用,必須異步調(diào)用。我們就用 setTimeout 解決異步問題
  • 如果 onFulfilled 或 onRejected 報錯,則直接返回 reject()
class myPromise {constructor(executor) {this.state = 'pending'this.value = undefinedthis.reason = undefinedthis.onResolvedCallbacks = []this.onRejectedCallbacks = []let resolve = value => {if (this.state === 'pending') {this.state = 'fulfilled'}this.value = valuethis.onResolvedCallbacks.forEach(fn => fn());}let reject = reason => {if (this.state === 'pending') {this.state = 'rejected'}this.reason = reasonthis.onRejectedCallbacks.forEach(fn => fn())}try {executor(resolve, reject)} catch(err) {reject(err)}}then(onFulfilled, onRejected) {// onFulfilled 如果不是函數(shù),忽略 onFulfilled, 直接返回 valueonFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val// onRejected 如果不是函數(shù),忽略 onRejected, 讓它等于一個函數(shù),并且在函數(shù)內(nèi)繼續(xù)將 err 向下拋出onRejected = typeof onRejected === 'function' ? onRejected : err => {throw err}let promise2 = new Promise((resolve, reject) => {if (this.state === 'fulfilled') {// 異步setTimeout(() => {try {let x = onFulfilled(this.value)resolvePromise(promise2, x, resolve, reject)} catch(err) {reject(err)}}, 0)}if (this.state === 'rejected') {// 異步setTimeout(() => {try {let x = onRejected(this.reason)resolvePromise(promise2, x, resolve, reject)} catch(err) {reject(err)}}, 0)}if (this.state === 'pending') {this.onResolvedCallbacks.push(() => {// 異步setTimeout(() => {try {let x = onFulfilled(this.value)resolvePromise(promise2, x, resolve, reject)} catch(err) {reject(err)}}, 0)})this.onRejectedCallbacks.push(() => {// 異步setTimeout(() => {try {let x = onRejected(this.reason)resolvePromise(promise2, x, resolve, reject)} catch(err) {reject(err)}}, 0)})}})return promise2}
}
添加 catch 方法
class myPromise {constructor(executor) {...}then(onFulfilled, onRejected) {...}// Promise 中的 catch 指代的就是 then 沒有成功回調(diào)的一個別名而已catch(errCallback) {return this.then(null, errCallback);}
}
添加 finally 方法
// 無論如何都會執(zhí)行,把上一個 then 的結果向下傳遞
// 如果 finally 中返回了一個 Promise 會等待這個 Promise 執(zhí)行完成后繼續(xù)執(zhí)行
myPromise.prototype.finally = function(callback) {return this.then(val => {return Promise.resolve(callback()).then(() => val);}, (err) => {return Promise.resolve(callback()).then(() => { throw err; });});
};
添加 resolve、reject、race、all 等方法
// Promise.resolve 會等待里面的 Promise 執(zhí)行成功
Promise.resolve = val => {return new Promise((resolve) => {resolve(val);});
};// Promise.reject 不會等待參數(shù)中的 Promise 執(zhí)行完畢
Promise.reject = () => {return new Promise((_, reject) => {reject(val);});
};// all 方法表示等待所有的 Promise 全部成功后才會執(zhí)行回調(diào)
// 如果有一個 Promise 失敗則 Promise 就失敗了
Promise.all = promises => {return new Promise((resolve, reject) => {// 存放結果const res = [];// 計數(shù),當count 等于 length的時候就resolvelet count = 0;const resolveRes = (index, data) => {// 將執(zhí)行結果緩存在res中res[index] = data;// 所有子項執(zhí)行完畢之后,執(zhí)行resolve 拋出所有的執(zhí)行結果if (++count === promises.length) {resolve(res);}};// 循環(huán)遍歷每一個參數(shù)的每一項for(let i = 0; i < promises.length; i++) {const current = promises[i];// 如果當前項是Promise,則返回 then 的結果if (isPromise(current)) {current.then((data) => {resolveRes(i, data);}, (err) => {reject(err);});} else {resolveRes(i, current);}}});
}// race誰是第一個完成的,就用他的結果
// 如果失敗這個 Promise 就失敗,如果第一個是成功就是成功
Promise.race = (promises) => {return new Promise((resolve, reject) => {for(let i = 0; i < promises.length; i++) {let current = promises[i];// 如果是一個 promise 繼續(xù)執(zhí)行 thenif (isPromise(current)) {current.then(resolve, reject);} else {// 是普通值則直接 resolve 返回,并終止循環(huán)resolve(current);break;}}});
}
如何驗證我們的 Promise 是否正確?
  1. 先在后面加上下述代碼
    // 目前是通過他測試 他會測試一個對象
    // 語法糖
    Promise.defer = Promise.deferred = function () {let dfd = {}dfd.promise = new Promise((resolve,reject)=>{dfd.resolve = resolve;dfd.reject = reject;});return dfd;
    }
    module.exports = Promise;
    //npm install promises-aplus-tests 用來測試自己的 promise 符不符合 promises A+ 規(guī)范
  2. npm 有一個 promises-aplus-tests 插件
    // Windows 全局安裝
    npm i promises-aplus-tests -g
    // Mac 全局安裝
    sudo npm i promises-aplus-tests -g
  3. 命令行 promises-aplus-tests [js文件名],即可驗證

注意??:本文 Promise 已滿足基本使用,但還是存在一些問題待改進。。。

參考

史上最最最詳細的手寫Promise教程

Promise 實現(xiàn)原理

http://www.risenshineclean.com/news/52039.html

相關文章:

  • 超鏈接網(wǎng)站圖片怎么在記事本上做長沙官網(wǎng)seo收費
  • 常州網(wǎng)站推廣多少錢域名備案查詢
  • 百度推廣客服人工電話多少安卓手機優(yōu)化軟件排名
  • 昆山企業(yè)網(wǎng)站建設河南關鍵詞排名顧問
  • 合肥模板建站多少錢網(wǎng)絡營銷方式有哪些
  • 靜態(tài)網(wǎng)站怎么做留言板南京谷歌seo
  • css3網(wǎng)站案例今天最新的新聞頭條
  • 網(wǎng)站開發(fā)與維護算什么職位成都seo推廣員
  • 游戲動漫設計專業(yè)網(wǎng)店seo名詞解釋
  • php 做視頻網(wǎng)站免費b站推廣網(wǎng)站
  • 做ppt到哪個網(wǎng)站找圖片十大成功營銷策劃案例
  • 登封市建設局網(wǎng)站廣告制作公司
  • 濟源做網(wǎng)站的好公司seo線上培訓班
  • 大豐做網(wǎng)站的公司付費內(nèi)容網(wǎng)站
  • 電子商務網(wǎng)站建設步驟信息流廣告投放工作內(nèi)容
  • b2b網(wǎng)站用戶群劃分鄭州疫情最新情況
  • h5企業(yè)網(wǎng)站開發(fā)專業(yè)搜索引擎seo服務
  • 邵陽微網(wǎng)站開發(fā)lz2v廣告行業(yè)怎么找客戶
  • 自己做的網(wǎng)站怎么做客服聊天深圳百度關鍵詞排名
  • 河南省豫建設計院網(wǎng)站軟文廣告投放平臺
  • 義網(wǎng)站建設推薦鄭國華如何做一個自己的網(wǎng)頁
  • 南京建設工程管理局網(wǎng)站游戲代理怎么找渠道
  • 微信輔助做任務網(wǎng)站seo服務外包費用
  • 服務器租用多少錢一月端點seo博客
  • 空間商網(wǎng)站網(wǎng)站是如何建立的
  • 哪個網(wǎng)站可以做圖片杭州專業(yè)seo公司
  • 深圳制作手機網(wǎng)站制作app平臺需要多少錢
  • 平臺網(wǎng)站設計廣西壯族自治區(qū)免費百度推廣
  • 山西網(wǎng)站建設推廣百度手機端排名如何優(yōu)化
  • 上海網(wǎng)站推廣珈維互動營銷案例100