最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Javascript promise異步編程淺析

 更新時(shí)間:2023年04月21日 11:10:26   作者:葉落風(fēng)塵  
這篇文章主要介紹了Javascript promise異步編程,Promise 是異步編程的一種解決方案,可以替代傳統(tǒng)的解決方案–回調(diào)函數(shù)和事件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧

promise 是什么

Promise 是異步編程的一種解決方案,可以替代傳統(tǒng)的解決方案–回調(diào)函數(shù)和事件。ES6 統(tǒng)一了用法,并原生提供了 Promise 對(duì)象。作為對(duì)象,Promise 有以下兩個(gè)特點(diǎn):

(1)對(duì)象的狀態(tài)不受外界影響。

(2)一旦狀態(tài)改變了就不會(huì)再變,也就是說任何時(shí)候 Promise 都只有一種狀態(tài)。

Promise 有三種狀態(tài),分別是 Pending (進(jìn)行中)、Resolved (已完成)、Rejected (已失敗)。Promise 從 Pending 狀態(tài)開始,如果成功就轉(zhuǎn)到成功態(tài),并執(zhí)行 resolve 回調(diào)函數(shù);如果失敗就轉(zhuǎn)到失敗狀態(tài)并執(zhí)行 reject 回調(diào)函數(shù)。

可以通過 Promise 的構(gòu)造函數(shù)創(chuàng)建 Promise 對(duì)象

var promise = new Promise((resolve,reject) => {
  setTimeout(()=>{
    console.log("hello world")
}, 2000)
})

Promise 構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù),該函數(shù)的兩個(gè)參數(shù)是 resolve ,reject,它們由 JavaScript 引擎提供。其中 resolve 函數(shù)的作用是當(dāng) Promise 對(duì)象轉(zhuǎn)移到成功,調(diào)用 resolve 并將操作結(jié)果作為其參數(shù)傳遞出去;reject 函數(shù)的作用是當(dāng) Promise 對(duì)象的狀態(tài)變?yōu)槭r(shí),將操作報(bào)出的錯(cuò)誤作為參數(shù)傳遞出去。如下代碼:

function greet(){
  var promise = new Promise(function(resolve,reject){
    var greet = "hello world"
    resolve(greet)
})
  return promise
}
greet().then(v=>{
  console.log(v)//*
})

Promise 的 then 方法,promise 的 then 方法帶有一下三個(gè)參數(shù):成功的回調(diào),失敗的回調(diào),前進(jìn)的回調(diào)。一般情況下只需要實(shí)現(xiàn)第一個(gè),后面的是可選的。Promise 中最為重要的狀態(tài),通過 then 的狀態(tài)傳遞可以實(shí)現(xiàn)的回調(diào)函數(shù)鏈?zhǔn)讲僮鞯膶?shí)現(xiàn)。先執(zhí)行以下代碼:

function greet () {
  var promise = new Promise (function(resolve, reject){
    var greet = "hello world"
    resolve(greet)
  })
  return promise
}
var p = greet().then(v => {
  console.log(v)  // Promise { <pending> }
})
console.log(p)  // hello world

catch 用法

function judgeNumber(num){
    var promise1 = new Promise(function(resolve,reject){
        num =5;
        if(num<5){
            resolve("num小于5,值為:"+num);
        }else{
            reject("num不小于5,值為:"+num);
        }
    });
    return promise1;
}
judgeNumber().then(
    function(message){
        console.log(message);
    }
)
.catch(function(message){
    console.log(message);
})

Promise 的 all 方法提供了并行執(zhí)行異步操作的能力,在 all 中所有異步操作結(jié)束后才執(zhí)行回調(diào)。

function p1(){
    var promise1 = new Promise(function(resolve,reject){
        console.log("p1的第一條輸出語句");
        console.log("p1的第二條輸出語句");
        resolve("p1完成");
    })
    return promise1;
}
function p2(){
    var promise2 = new Promise(function(resolve,reject){
        console.log("p2的第一條輸出語句");
        setTimeout(()=>{console.log("p2的第二條輸出語句");resolve("p2完成")},2000);
    })
    return promise2;
}
function p3(){
    var promise3 = new Promise(function(resolve,reject){
        console.log("p3的第一條輸出語句");
        console.log("p3的第二條輸出語句");
        resolve("p3完成")
    });
    return  promise3;
}
Promise.all([p1(),p2(),p3()]).then(function(data){
    console.log(data);
})
p1的第一條輸出語句
p1的第二條輸出語句
p2的第一條輸出語句
p3的第一條輸出語句
p3的第二條輸出語句
p2的第二條輸出語句
['p1完成', 'p2完成', 'p3完成']

在 all 中的回調(diào)函數(shù)中,等到所有的 Promise 都執(zhí)行完,再來執(zhí)行回調(diào)函數(shù),race 則不同它等到第一個(gè) Promise 改變狀態(tài)就開始執(zhí)行回調(diào)函數(shù)。將上面的all改為race,得到

Promise.race([p1(),p2(),p3()]).then(function(data){
    console.log(data);
})

如何實(shí)現(xiàn)一個(gè) promise

(function(window,undefined){
// resolve 和 reject 最終都會(huì)調(diào)用該函數(shù)
var final = function(status,value){
    var promise = this, fn, st;
    if(promise._status !== 'PENDING') return;
    // 所以的執(zhí)行都是異步調(diào)用,保證then是先執(zhí)行的
    setTimeout(function(){
        promise._status = status;
        st = promise._status === 'FULFILLED'
        queue = promise[st ? '_resolves' : '_rejects'];
        while(fn = queue.shift()) {
            value = fn.call(promise, value) || value;
        }
        promise[st ? '_value' : '_reason'] = value;
        promise['_resolves'] = promise['_rejects'] = undefined;
    });
}
//參數(shù)是一個(gè)函數(shù),內(nèi)部提供兩個(gè)函數(shù)作為該函數(shù)的參數(shù),分別是resolve 和 reject
var Promise = function(resolver){
    if (!(typeof resolver === 'function' ))
        throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
    //如果不是promise實(shí)例,就new一個(gè)
    if(!(this instanceof Promise)) return new Promise(resolver);
    var promise = this;
    promise._value;
    promise._reason;
    promise._status = 'PENDING';
    //存儲(chǔ)狀態(tài)
    promise._resolves = [];
    promise._rejects = [];
    //
    var resolve = function(value) {
        //由於apply參數(shù)是數(shù)組
        final.apply(promise,['FULFILLED'].concat([value]));
    }
    var reject = function(reason){
        final.apply(promise,['REJECTED'].concat([reason]));
    }
    resolver(resolve,reject);
}
Promise.prototype.then = function(onFulfilled,onRejected){
    var promise = this;
    // 每次返回一個(gè)promise,保證是可thenable的
    return new Promise(function(resolve,reject){
        function handle(value) {
            // 這一步很關(guān)鍵,只有這樣才可以將值傳遞給下一個(gè)resolve
            var ret = typeof onFulfilled === 'function' && onFulfilled(value) || value;
            //判斷是不是promise 對(duì)象
            if (ret && typeof ret ['then'] == 'function') {
                ret.then(function(value) {
                    resolve(value);
                }, function(reason) {
                    reject(reason);
                });
            } else {
                resolve(ret);
            }
        }
        function errback(reason){
            reason = typeof onRejected === 'function' && onRejected(reason) || reason;
            reject(reason);
        }
        if(promise._status === 'PENDING'){
            promise._resolves.push(handle);
            promise._rejects.push(errback);
        }else if(promise._status === FULFILLED){ // 狀態(tài)改變后的then操作,立刻執(zhí)行
            callback(promise._value);
        }else if(promise._status === REJECTED){
            errback(promise._reason);
        }
    });
}
Promise.prototype.catch = function(onRejected){
    return this.then(undefined, onRejected)
}
Promise.prototype.delay = function(ms,value){
    return this.then(function(ori){
        return Promise.delay(ms,value || ori);
    })
}
Promise.delay = function(ms,value){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve(value);
            console.log('1');
        },ms);
    })
}
Promise.resolve = function(arg){
    return new Promise(function(resolve,reject){
        resolve(arg)
    })
}
Promise.reject = function(arg){
    return Promise(function(resolve,reject){
        reject(arg)
    })
}
Promise.all = function(promises){
    if (!Array.isArray(promises)) {
        throw new TypeError('You must pass an array to all.');
    }
    return Promise(function(resolve,reject){
        var i = 0,
            result = [],
            len = promises.length,
            count = len
        //這里與race中的函數(shù)相比,多了一層嵌套,要傳入index
        function resolver(index) {
          return function(value) {
            resolveAll(index, value);
          };
        }
        function rejecter(reason){
            reject(reason);
        }
        function resolveAll(index,value){
            result[index] = value;
            if( --count == 0){
                resolve(result)
            }
        }
        for (; i < len; i++) {
            promises[i].then(resolver(i),rejecter);
        }
    });
}
Promise.race = function(promises){
    if (!Array.isArray(promises)) {
        throw new TypeError('You must pass an array to race.');
    }
    return Promise(function(resolve,reject){
        var i = 0,
            len = promises.length;
        function resolver(value) {
            resolve(value);
        }
        function rejecter(reason){
            reject(reason);
        }
        for (; i < len; i++) {
            promises[i].then(resolver,rejecter);
        }
    });
}
window.Promise = Promise;
})(window);

async await

async 表示這是一個(gè) async 函數(shù), await 只能用在 async 函數(shù)里面,不能單獨(dú)使用

async 返回的是一個(gè) Promise 對(duì)象,await 就是等待這個(gè) promise 的返回結(jié)果后,再繼續(xù)執(zhí)行

await 等待的是一個(gè) Promise 對(duì)象,后面必須跟一個(gè) Promise 對(duì)象,但是不必寫 then(),直接就可以得到返回值

async/await 的優(yōu)點(diǎn)

方便級(jí)聯(lián)調(diào)用:即調(diào)用依次發(fā)生的場景;

同步代碼編寫方式:Promise 使用 then 函數(shù)進(jìn)行鏈?zhǔn)秸{(diào)用,一直點(diǎn)點(diǎn)點(diǎn),是一種從左向右的橫向?qū)懛ǎ籥sync/await 從上到下,順序執(zhí)行,就像寫同步代碼一樣,更符合代碼編寫習(xí)慣;

多個(gè)參數(shù)傳遞:Promise 的 then 函數(shù)只能傳遞一個(gè)參數(shù),雖然可以通過包裝成對(duì)象來傳遞多個(gè)參數(shù),但是會(huì)導(dǎo)致傳遞冗余信息,頻繁的解析又重新組合參數(shù),比較麻煩;async/await 沒有這個(gè)限制,可以當(dāng)做普通的局部變量來處理,用 let 或者 const 定義的塊級(jí)變量想怎么用就怎么用,想定義幾個(gè)就定義幾個(gè),完全沒有限制,也沒有冗余工作;

同步代碼和異步代碼可以一起編寫:使用 Promise 的時(shí)候最好將同步代碼和異步代碼放在不同的 then 節(jié)點(diǎn)中,這樣結(jié)構(gòu)更加清晰;async/await 整個(gè)書寫習(xí)慣都是同步的,不需要糾結(jié)同步和異步的區(qū)別,當(dāng)然,異步過程需要包裝成一個(gè) Promise 對(duì)象放在 await 關(guān)鍵字后面;

基于協(xié)程:Promise 是根據(jù)函數(shù)式編程的范式,對(duì)異步過程進(jìn)行了一層封裝,async/await 基于協(xié)程的機(jī)制,是真正的“保存上下文,控制權(quán)切換……控制權(quán)恢復(fù),取回上下文”這種機(jī)制,是對(duì)異步過程更精確的一種描述;

async/await 是對(duì) Promise 的優(yōu)化:async/await 是基于 Promise 的,是進(jìn)一步的一種優(yōu)化,不過在寫代碼時(shí),Promise 本身的 API 出現(xiàn)得很少,很接近同步代碼的寫法

到此這篇關(guān)于Javascript promise異步編程淺析的文章就介紹到這了,更多相關(guān)Js promise異步內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript sort排序的使用方法詳解

    JavaScript sort排序的使用方法詳解

    這篇文章主要介紹了JavaScript sort排序的使用方法,sort方法用于對(duì)數(shù)組的元素進(jìn)行排序,排序順序可以是字母或數(shù)字,并按升序或降序,默認(rèn)排序順序?yàn)榘醋帜干?需要的朋友可以參考下
    2024-10-10
  • JavaScript中關(guān)于遞歸與回溯的實(shí)例詳解

    JavaScript中關(guān)于遞歸與回溯的實(shí)例詳解

    這篇文章主要將為大家介紹一下JavaScript中遞歸與回溯的原理及使用,文中通過一些例題進(jìn)行了詳細(xì)介紹,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-07-07
  • 利用JavaScript編寫一個(gè)簡單的1024小游戲

    利用JavaScript編寫一個(gè)簡單的1024小游戲

    在每年的10月24日,我們都會(huì)慶祝程序員節(jié),這是一個(gè)向所有辛勤工作、創(chuàng)造出無數(shù)令人驚嘆應(yīng)用和系統(tǒng)的程序員們致敬的日子,為了紀(jì)念這個(gè)特殊的日子,我們將通過編寫一個(gè)簡單的1024小游戲來向所有程序員們表示敬意,本文將詳細(xì)解釋如何使用JavaScript編寫這個(gè)小游戲
    2023-10-10
  • 用JS實(shí)現(xiàn)一個(gè)簡單的打磚塊游戲

    用JS實(shí)現(xiàn)一個(gè)簡單的打磚塊游戲

    這篇文章主要介紹了用JS實(shí)現(xiàn)一個(gè)簡單的打磚塊游戲,代碼分為html+css+js三部分,具體實(shí)例代碼感興趣的朋友跟隨小編一起看看吧
    2019-12-12
  • Webpack性能優(yōu)化 DLL 用法詳解

    Webpack性能優(yōu)化 DLL 用法詳解

    本篇文章主要介紹了Webpack DLL 用法詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • JavaScript中函數(shù)的防抖與節(jié)流詳解

    JavaScript中函數(shù)的防抖與節(jié)流詳解

    這篇文章主要為大家詳細(xì)介紹了JavaScript中函數(shù)的防抖與節(jié)流,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • js 第二代身份證號(hào)碼的驗(yàn)證機(jī)制代碼

    js 第二代身份證號(hào)碼的驗(yàn)證機(jī)制代碼

    在盛大某網(wǎng)站注冊的時(shí)候,身份證必填,但我又不想填真實(shí)身份證號(hào)碼,于是隨便編了串自認(rèn)為合法的身份證號(hào)碼,但是卻馬上被提示號(hào)碼錯(cuò)誤
    2011-05-05
  • 詳解全棧開發(fā)Vercel數(shù)據(jù)庫存儲(chǔ)服務(wù)

    詳解全棧開發(fā)Vercel數(shù)據(jù)庫存儲(chǔ)服務(wù)

    這篇文章主要為大家介紹了全棧開發(fā)Vercel數(shù)據(jù)庫存儲(chǔ)服務(wù)功能使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • JS如何獲取對(duì)象鍵值對(duì)中key值的方法

    JS如何獲取對(duì)象鍵值對(duì)中key值的方法

    這篇文章主要介紹了JS如何獲取對(duì)象鍵值對(duì)中key值的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • javascript的var與let,const之間的區(qū)別詳解

    javascript的var與let,const之間的區(qū)別詳解

    這篇文章主要為大家介紹了?javascript的var與let,const之間的區(qū)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12

最新評(píng)論

同仁县| 平罗县| 龙川县| 桐梓县| 南和县| 嘉定区| 宁武县| 吉木萨尔县| 甘泉县| 惠来县| 濮阳县| 清水河县| 泗洪县| 荆州市| 宜阳县| 五常市| 泾阳县| 忻城县| 双辽市| 淳化县| 宝应县| 玉溪市| 靖江市| 改则县| 友谊县| 陆良县| 高碑店市| 思茅市| 娄烦县| 禹城市| 剑河县| 广灵县| 莒南县| 金堂县| 疏附县| 丹东市| 宁津县| 鲁甸县| 青河县| 海宁市| 百色市|