成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

promise學(xué)習(xí)(1)

pingink / 888人閱讀

摘要:原文地址定義是針對(duì)異步編程的一種解決方案,能夠抽象處理異步對(duì)象以及對(duì)其進(jìn)行操作。當(dāng)狀態(tài)由時(shí)執(zhí)行已完成的回調(diào)函數(shù),由時(shí),調(diào)用失敗的回調(diào)函數(shù)。所以,可以在自行使用,保證執(zhí)行不會(huì)出錯(cuò),或者使用其他異步編程方式。異步編程的方案后續(xù)學(xué)習(xí)再補(bǔ)充

原文地址

定義

Promise是針對(duì)異步編程的一種解決方案,能夠抽象處理異步對(duì)象以及對(duì)其進(jìn)行操作。Promise并不是Javascript語(yǔ)言的擴(kuò)展,只是在ES6中將其寫(xiě)進(jìn)了語(yǔ)言標(biāo)準(zhǔn),原生Javascript提供了Promise對(duì)象,統(tǒng)一了用法。

功能

可以在一定程度上優(yōu)化回調(diào)地獄問(wèn)題,當(dāng)需要控制多個(gè)異步操作時(shí),代碼結(jié)構(gòu)更加清晰,便于理解。

提供統(tǒng)一的API,書(shū)寫(xiě)更加規(guī)范,便于維護(hù),便于控制異步操作。

原理

一個(gè) Promise 對(duì)象代表一個(gè)目前還不可用,但是在未來(lái)的某個(gè)時(shí)間點(diǎn)可以被解析的值。

可以理解為Promise能夠以同步的方式編寫(xiě)異步代碼,但是有更優(yōu)的解決方式。

Promise的狀態(tài)

Promise對(duì)象存在三種狀態(tài):pending、fulfilled、rejected。其中pending 狀態(tài)最終一定會(huì)變?yōu)閒ulfilled或者是rejected中的一種,且不會(huì)再發(fā)生改變。整個(gè)過(guò)程由Promise機(jī)制保證不會(huì)受到外界干擾。當(dāng)狀態(tài)由pending->fulfilled時(shí)執(zhí)行已完成的回調(diào)函數(shù),由pending->rejected時(shí),調(diào)用失敗的回調(diào)函數(shù)。一旦狀態(tài)改變,就不會(huì)再被修改而一直保持這個(gè)狀態(tài)。

基本API

實(shí)例方法

Promise#then

Promise#catch

靜態(tài)方法

Promise.resolve

Promise.reject

Promise.all

Promise.race

問(wèn)題&思考 什么是同步,什么是異步?

大家常說(shuō)Javascript是單線程的語(yǔ)言,這固然是對(duì)的。這里的單線程是說(shuō),在JS引擎中負(fù)責(zé)解釋和執(zhí)行JavaScript代碼的線程只有一個(gè),每個(gè)特定的時(shí)刻只有特定的代碼被執(zhí)行,并阻塞其他代碼。換句話說(shuō),JavaScript是單線程,但是瀏覽器是多線程的。除了負(fù)責(zé)解析JS代碼之外,還存在其他線程,負(fù)責(zé)HTTP請(qǐng)求,DOM處理等等。

同步可以理解成在一個(gè)函數(shù)返回時(shí),我就拿到了需要的結(jié)果,無(wú)需等待。異步則是函數(shù)返回時(shí),我沒(méi)有得到應(yīng)該得到的結(jié)果,而且要在未來(lái)某一時(shí)間才能得到。程序執(zhí)行的順序和任務(wù)執(zhí)行的順序并不始終保持一致。

前端的哪些操作需要使用異步編程?

常見(jiàn)的操作有接口請(qǐng)求,文件讀取,定時(shí)器操作等。在瀏覽器端耗時(shí)很長(zhǎng)的操作,最好都異步執(zhí)行。(鼠標(biāo)點(diǎn)擊事件、窗口大小拖拉事件等也可以算是異步的)

Promise概念和使用上有哪些需要注意的地方?
關(guān)于Promise的狀態(tài)

promise對(duì)象的狀態(tài),只有對(duì)象處于pending狀態(tài)時(shí)是可變的,一旦從Pending轉(zhuǎn)換為FulfilledRejected之后, 這個(gè)promise對(duì)象的狀態(tài)就不會(huì)再發(fā)生任何變化。也就是說(shuō),Promise與Event等不同,在.then 后執(zhí)行的函數(shù)可以肯定地說(shuō)只會(huì)被調(diào)用一次,而且只會(huì)執(zhí)行fulfilled或者rejected中的一個(gè)。

創(chuàng)建promise對(duì)象

一般情況下會(huì)使用new Promise創(chuàng)建對(duì)象,除此之外,也可以使用其他方法。

靜態(tài)方法Promise.resolve(value) 可以認(rèn)為是new Promise()方法的快捷方式,同理Promise.reject(error)也是。

thenable對(duì)象&promise對(duì)象

thenable對(duì)象和promise對(duì)象并不是一回事,thenable對(duì)象可以理解為具有.then方法的對(duì)象。

可以通過(guò)Promise.resolve將thenable對(duì)象轉(zhuǎn)化為promise對(duì)象。

Promise鏈?zhǔn)秸{(diào)用

promise的鏈?zhǔn)秸{(diào)用可以通過(guò)使用.then處理回調(diào)函數(shù)比較多的情況,一定程度上解決回調(diào)地獄的問(wèn)題。鏈?zhǔn)秸{(diào)用的原理(后續(xù)可以多帶帶介紹下)簡(jiǎn)單來(lái)說(shuō)是Promise內(nèi)部有一個(gè)defers隊(duì)列存放事件,程序執(zhí)行時(shí).then將下個(gè)事件放入,promise狀態(tài)變化結(jié)束之后出發(fā)響應(yīng)函數(shù)執(zhí)行,然后將事件從隊(duì)列中移除。因?yàn)槊恳淮握{(diào)用.then時(shí)都會(huì)創(chuàng)建一個(gè)全新的promise對(duì)象,所以保證了鏈?zhǔn)秸{(diào)用可以順利執(zhí)行。

鏈?zhǔn)秸{(diào)用的參數(shù)傳遞順序

demo1

前一個(gè)task的返回值作為后一個(gè)task的參數(shù)。不使用鏈?zhǔn)秸{(diào)用,直接調(diào)用.then方法時(shí),由于每次都是新建的promise對(duì)象,所以value的值始終為100。

// 1: 對(duì)同一個(gè)promise對(duì)象同時(shí)調(diào)用 then 方法
var aPromise = new Promise(function (resolve) {
    resolve(100);
});
aPromise.then(function (value) {
    return value * 2;
});
aPromise.then(function (value) {
    return value * 2;
});
aPromise.then(function (value) {
    console.log("1: " + value); // => 100
})
// vs
// 2: 對(duì) then 進(jìn)行 promise chain 方式進(jìn)行調(diào)用
var bPromise = new Promise(function (resolve) {
    resolve(100);
});
bPromise.then(function (value) {
    return value * 2;
}).then(function (value) {
    return value * 2;
}).then(function (value) {
    console.log("2: " + value); // => 100 * 2 * 2
});
鏈?zhǔn)秸{(diào)用多個(gè)task的執(zhí)行順序

在鏈?zhǔn)秸{(diào)用過(guò)程中,每一個(gè).then調(diào)用時(shí)候都會(huì)創(chuàng)建一個(gè)全新的promise對(duì)象,.then調(diào)用結(jié)束時(shí)會(huì)執(zhí)行對(duì)應(yīng)狀態(tài)的回調(diào)函數(shù),

但是如果沒(méi)有傳入rejected的回調(diào),或者.catch使用的位置不同,都會(huì)導(dǎo)致最后的結(jié)果不同。

demo2

task全部正常執(zhí)行:

function taskA() {
    console.log("Task A");
}
function taskB() {
    console.log("Task B");
}
function onRejected(error) {
    console.log("Catch Error: A or B", error);
}
function finalTask() {
    console.log("Final Task");
}
var promise = Promise.resolve();
promise
    .then(taskA)
    .then(taskB)
    .catch(onRejected)
    .then(finalTask);

輸出結(jié)果為:

Task A
Task B
Final Task

當(dāng)taskA執(zhí)行失敗時(shí):

function taskA() {
    console.log("Task A");
    throw new Error("throw Error @ Task A")
}

輸出結(jié)果為:

Task A
Error: throw Error @ Task A
Final Task

由于taskB中并沒(méi)有注冊(cè)rejected函數(shù),所以taskB并未執(zhí)行,而是直接通過(guò)catch捕獲到了失敗。

如果在taskB的then中傳入了失敗的回調(diào):

promise
    .then(taskA)
    .then(taskB,function(error) {
        console.log("b-catch-error")
    })
    .catch(onRejected)
    .then(finalTask);

執(zhí)行結(jié)果為:

Task A
b-catch-error
Final Task

所以,在多個(gè).then鏈?zhǔn)秸{(diào)用時(shí),不同位置報(bào)錯(cuò)會(huì)導(dǎo)致task執(zhí)行順序不同,執(zhí)行不同,也許不符合預(yù)期。

所以,可以在自行使用try-catch,保證.then執(zhí)行不會(huì)出錯(cuò),或者使用其他異步編程方式。

每一次調(diào)用.then,都會(huì)返回新的Promise對(duì)象

demo3

下面代碼中每一次返回的promise對(duì)象都不是同一個(gè)對(duì)象。

var aPromise = new Promise(function (resolve) {
    resolve(100);
});
var thenPromise = aPromise.then(function (value) {
    console.log(value);
});
var catchPromise = thenPromise.catch(function (error) {
    console.error(error);
});
console.log(aPromise !== thenPromise); // => true
console.log(thenPromise !== catchPromise);// => true

理解了這個(gè)再來(lái)看下面的問(wèn)題。

demo4 錯(cuò)誤的調(diào)用

function badAsyncCall() {
    var promise = Promise.resolve();
    promise.then(function() {
        // 任意處理
        return 1;
    });
    return promise;
}

demo5 正確的調(diào)用

function anAsyncCall() {
    var promise = Promise.resolve();
    return promise.then(function() {
        // 任意處理
        return 1;
    });
}

返回結(jié)果

demo4中return 的promise并不是執(zhí)行過(guò).then的promise,所以并沒(méi)有返回預(yù)期的結(jié)果。在實(shí)際開(kāi)發(fā)中要注意這個(gè)問(wèn)題。

rejected并不一定會(huì)捕獲到異常

但看這個(gè)字面上可能會(huì)有些疑惑,實(shí)際上還是概念上的問(wèn)題。

使用promise.then(Fulfilled, Rejected)的話,在Fulfilled 中發(fā)生異常的話,在Rejected中是捕獲不到這個(gè)異常的。原因是promise狀態(tài)只能從pending變成fulfilled或者是rejected,且變化完成之后不會(huì)再被修改。所以一旦執(zhí)行了fulfilled,說(shuō)明promise成功了,此時(shí)就已經(jīng)不會(huì)再執(zhí)行rejected了。

promise 不要在異步和同步混合使用

demo6

function onReady(fn) {
    var readyState = document.readyState;
    if (readyState === "interactive" || readyState === "complete") {
        fn();
    } else {
        window.addEventListener("DOMContentLoaded", fn);
    }
}
onReady(function () {
    console.log("DOM fully loaded and parsed");
});
console.log("==Starting==");

如果這段代碼在源文件中出現(xiàn)的位置不同,在控制臺(tái)上打印的log消息順序也會(huì)不同。 結(jié)果不可控這是極力要避免的。

正確的寫(xiě)法應(yīng)該是:

function onReadyPromise() {
    return new Promise(function (resolve, reject) {
        var readyState = document.readyState;
        if (readyState === "interactive" || readyState === "complete") {
            resolve();
        } else {
            window.addEventListener("DOMContentLoaded", resolve);
        }
    });
}
onReadyPromise().then(function () {
    console.log("DOM fully loaded and parsed");
});
console.log("==Starting==");

為了避免上述中同時(shí)使用同步、異步調(diào)用可能引起的混亂問(wèn)題,Promise在規(guī)范上規(guī)定 Promise只能使用異步調(diào)用方式

異步編程的方案

(后續(xù)學(xué)習(xí)再補(bǔ)充)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96697.html

相關(guān)文章

  • 深入學(xué)習(xí)Promise調(diào)用鏈

    摘要:前言使用中,鏈?zhǔn)降恼{(diào)用對(duì)于控制異步執(zhí)行很重要。的鏈?zhǔn)秸{(diào)用是支持鏈?zhǔn)秸{(diào)用的,但是它是不同于上面的鏈?zhǔn)?。是調(diào)用方法返回自身,但是是調(diào)用方法后返回一個(gè)新的。的運(yùn)行機(jī)制請(qǐng)參考的運(yùn)行機(jī)制值穿透由于通過(guò)沒(méi)有成功添加回調(diào)函數(shù),發(fā)生了值穿透。 前言 使用Promise中,鏈?zhǔn)降恼{(diào)用對(duì)于控制異步執(zhí)行很重要。 鏈?zhǔn)秸{(diào)用 在jQuery的使用中,我們常常使用下面的代碼 $(#app).show().css(...

    tianren124 評(píng)論0 收藏0
  • promise學(xué)習(xí)(2)

    摘要:所謂的能對(duì)狀態(tài)進(jìn)行操作的特權(quán)方法,指的就是能對(duì)對(duì)象的狀態(tài)進(jìn)行等調(diào)用的方法,而通常的的話只能在通過(guò)構(gòu)造函數(shù)傳遞的方法之內(nèi)對(duì)對(duì)象的狀態(tài)進(jìn)行操作。一般會(huì)在構(gòu)造函數(shù)中編寫(xiě)邏輯,什么時(shí)候執(zhí)行回調(diào),什么時(shí)候執(zhí)行回調(diào)。 原文地址 1. 在then中使用reject 如果一個(gè)promise最初只定義了resolve,但是還想要使用reject怎么辦? 可以在then中返回一個(gè)新的promise。這個(gè)...

    firim 評(píng)論0 收藏0
  • Promise源碼學(xué)習(xí)(2)

    摘要:源碼學(xué)習(xí)本篇為上一篇源碼學(xué)習(xí)的補(bǔ)充,主要是來(lái)介紹和方法。那個(gè)率先改變的實(shí)例的返回值,就傳遞給的回調(diào)函數(shù)?;窘榻B可見(jiàn)阮一峰老師的書(shū)籍。的狀態(tài)由決定,分成兩種情況。只有的狀態(tài)都變成,的狀態(tài)才會(huì)變成,此時(shí)的返回值組成一個(gè)數(shù)組,傳遞給的回調(diào)函數(shù)。 Promise源碼學(xué)習(xí)(2) 本篇為上一篇源碼學(xué)習(xí)(1)的補(bǔ)充,主要是來(lái)介紹Promise.all()和Promise.race()方法。閑話少敘...

    cfanr 評(píng)論0 收藏0
  • 嗨,了解一下,我的Promise學(xué)習(xí)筆記

    摘要:回調(diào)函數(shù)成功回調(diào)處理器失敗回調(diào)處理器用戶發(fā)送一個(gè)向百度服務(wù)器獲取數(shù)據(jù)的異步請(qǐng)求無(wú)阻塞高并發(fā)的的誕生更加嚴(yán)重的依賴(lài)異步操作才能完成無(wú)阻賽高并發(fā)的特性。 Promise Promise 是什么? 詞語(yǔ)本意: 發(fā)音:[?pr?m?s] 詞性:名詞, 翻譯:許諾,允諾。 MDN解釋 Promise 對(duì)象用于一個(gè)異步操作。 一個(gè)Promise表示一個(gè)現(xiàn)在,將來(lái)或永不可能可用的值。 按照書(shū)寫(xiě)方...

    yanest 評(píng)論0 收藏0
  • JavaScript基礎(chǔ)——深入學(xué)習(xí)async/await

    摘要:等待的基本語(yǔ)法該關(guān)鍵字的的意思就是讓編譯器等待并返回結(jié)果。這里并不會(huì)占用資源,因?yàn)橐婵梢酝瑫r(shí)執(zhí)行其他任務(wù)其他腳本或處理事件。接下來(lái),我們寫(xiě)一個(gè)火箭發(fā)射場(chǎng)景的小例子不是真的發(fā)射火箭 本文由云+社區(qū)發(fā)表 本篇文章,小編將和大家一起學(xué)習(xí)異步編程的未來(lái)——async/await,它會(huì)打破你對(duì)上篇文章Promise的認(rèn)知,竟然異步代碼還能這么寫(xiě)! 但是別太得意,你需要深入理解Promise后,...

    張金寶 評(píng)論0 收藏0
  • promise學(xué)習(xí)(3)

    摘要:此時(shí),由于只有一個(gè)的狀態(tài)能夠確定,所以執(zhí)行的是唯一那個(gè)確定狀態(tài)的函數(shù),而不會(huì)執(zhí)行其他的,但是并不會(huì)阻止其他的執(zhí)行。在實(shí)際應(yīng)用中,常用來(lái)設(shè)置超時(shí)操作,比如接口請(qǐng)求超時(shí)等。思考這個(gè)其實(shí)并不是矛盾,接受的是返回的的狀態(tài),與原來(lái)的沒(méi)有關(guān)系。 原文地址 Promise.race // `delay`毫秒后執(zhí)行resolve function timerPromisefy(delay) { ...

    阿羅 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<