成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

理解 Javascript 中的 Promise

chaos_G / 3109人閱讀

摘要:理解承諾有兩個(gè)部分。如果異步操作成功,則通過的創(chuàng)建者調(diào)用函數(shù)返回預(yù)期結(jié)果,同樣,如果出現(xiàn)意外錯(cuò)誤,則通過調(diào)用函數(shù)傳遞錯(cuò)誤具體信息。這將與理解對象密切相關(guān)。這個(gè)函數(shù)將創(chuàng)建一個(gè),該將在到秒之間的隨機(jī)數(shù)秒后執(zhí)行或。

想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!

背景

當(dāng)你第一次開始使用JavaScript時(shí),它會(huì)有點(diǎn)令人沮喪。 你會(huì)聽到有些人說JavaScript是同步編程語言,而其他人則認(rèn)為它是異步的。 你會(huì)聽到阻塞代碼,非阻塞代碼,事件驅(qū)動(dòng)設(shè)計(jì)模式,事件生命周期,函數(shù)堆棧,事件隊(duì)列,冒泡,polyfill,babel,angular,reactJS,vueJS 以及大量其他工具和庫。 不要煩惱,你不是第一個(gè)。 這也有一個(gè)術(shù)語,它被稱為 JavaScript 疲勞。

JavaScript疲勞: 當(dāng)人們使用不需要的工具來解決他們沒有的問題時(shí),就會(huì)出現(xiàn)JavaScript疲勞

JavaScript是一種同步編程語言。但是由于回調(diào)函數(shù),我們可以使它像異步編程語言一樣工作。

初學(xué)者的 Promise

JavaScript中的 promise 與現(xiàn)實(shí)生活中的承諾非常相似。首先讓我們看看現(xiàn)實(shí)生活中的承諾。

promise 詞典中的定義:保證某人會(huì)做某事或某件事會(huì)發(fā)生。

那么當(dāng)有人向你承諾時(shí),會(huì)發(fā)生什么呢?

承諾給你一個(gè)將會(huì)有所作為的保證。他們(做出承諾的人)是自己做還是別人做,這無關(guān)緊要。他們給你一個(gè)保證,在此基礎(chǔ)上你可以計(jì)劃一些事情。

諾言可以遵守,也可以違背。

當(dāng)一個(gè)承諾被遵守時(shí),你期望從這個(gè)承諾中得到什么。你可以利用承諾的結(jié)果來做進(jìn)一步的行動(dòng)或計(jì)劃。

當(dāng)一個(gè)承諾被打破時(shí),你會(huì)想知道為什么做出承諾的人不能履行他的承諾。一旦你知道了原因,并確認(rèn)承諾已經(jīng)被打破,你就可以計(jì)劃下一步要做什么或如何處理它。

在作出承諾的時(shí)候,我們所擁有的只是一種保證。我們不能立即采取行動(dòng)。我們可以決定和制定當(dāng)承諾被遵守(因此我們有了預(yù)期的結(jié)果)或違背(我們知道原因,因此我們可以計(jì)劃一個(gè)意外事件)時(shí)需要做什么。

有可能你根本就沒有收到承諾人的回復(fù)。在這種情況下,您寧愿保留一個(gè)時(shí)間閾值。如果承諾的人10天后不回來找我,我會(huì)認(rèn)為他有一些問題,不會(huì)遵守他的承諾。所以即使那個(gè)人在15天后回到你身邊,這對你來說也不再重要,因?yàn)槟阋呀?jīng)有了其他的計(jì)劃。

JavaScript中的 Promise

根據(jù)經(jīng)驗(yàn),對于JavaScript,我總是閱讀來自MDN Web文檔的文檔。在所有資源中,我認(rèn)為它們提供了最簡潔的細(xì)節(jié)。我閱讀了來自 MDSN Web文檔的promise 介紹,并嘗試了一些代碼來掌握它。

理解承諾有兩個(gè)部分?!皠?chuàng)建 promises” 和 “處理 promises”。雖然我們的大多數(shù)代碼通常會(huì)迎合其他庫創(chuàng)建的 promises 的處理,但完全理解這些 promises 肯定會(huì)有所幫助。一旦你過了初學(xué)階段,理解“創(chuàng)造promises ”同樣重要。

Promise 創(chuàng)建

讓我們看一下創(chuàng)建新promis的語法

構(gòu)造函數(shù)接受一個(gè)名為executor 的函數(shù)。 此執(zhí)行函數(shù)接受兩個(gè)參數(shù) resolve 和 reject,它們f都是函數(shù)。 Promise 通常用于更容易處理異步操作或阻塞代碼,其示例包括文件操作,API調(diào)用,DB調(diào)用,IO調(diào)用等。這些異步操作的啟動(dòng)發(fā)生在執(zhí)行函數(shù)中。如果異步操作成功,則通過 promise 的創(chuàng)建者調(diào)用resolve 函數(shù)返回預(yù)期結(jié)果,同樣,如果出現(xiàn)意外錯(cuò)誤,則通過調(diào)用 reject 函數(shù)傳遞錯(cuò)誤具體信息。

var keepsHisWord;
keepsHisWord = true;
promise1 = new Promise(function(resolve, reject) {
  if (keepsHisWord) {
    resolve("小智承諾堅(jiān)持分享好的東西給大家");
  } else {
    reject("我沒有做到!");
  }
});
console.log(promise1);

由于該 promise 會(huì)立即執(zhí)行,我們將無法檢查該 promise 的初始狀態(tài)。因此,讓我們創(chuàng)造一個(gè)需要時(shí)間來執(zhí)行的 promise,最簡單的方法是使用 setTimeOut 函數(shù)。

promise2 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve({
      message: "小智承諾堅(jiān)持分享好的東西給大家",
      code: "200"
    });
  }, 10 * 1000);
});
console.log(promise2);

上面的代碼只是創(chuàng)建了一個(gè)在10秒后無條件執(zhí)行 promise。 因此,我們可以檢查promise 的狀態(tài),直到它被 resolve。

一旦十秒鐘過去,promise 就會(huì)執(zhí)行 resolve。PromiseStatus 和 PromiseValue 都會(huì)相應(yīng)地更新。如你所見,我們更新了 resolve 函數(shù),以便傳遞 JSON 對象,而不是簡單的字符串。這只是為了說明我們也可以在 resolve 函數(shù)中傳遞其他值。

現(xiàn)在讓我們看看一個(gè) promise reject的例子。我們只要修改一下 keepsHisWord:

我們可以看到 PromiseStatus 可以有三個(gè)不同的值,pending(進(jìn)行中)、 resolved(已成功) 或 rejected(失敗)。創(chuàng)建 promise 時(shí),PromiseStatus 將處于 pending 狀態(tài),并且 PromiseValue 為 undefined,直到 promise 被 resolved 或 rejected 為止。 當(dāng) promise 處于 resolved 或 rejected 的狀態(tài)時(shí),就稱為 settled(已定型)。 所以 promise 通常從 pending 態(tài)轉(zhuǎn)換到 settled 狀態(tài)。

既然我們知道 promise 是如何創(chuàng)建的,我們就可以看看如何使用或處理 promise。這將與理解 Promise 對象密切相關(guān)。

理解 Promise 對象

根據(jù) MDN 文檔

Promise 對象表示異步操作的最終完成(或失敗)及其結(jié)果值

Promise 對象具有靜態(tài)方法和原型方法,Promise 對象中的靜態(tài)方法可以獨(dú)立應(yīng)用,而原型方法需要應(yīng)用于 Promise對象的實(shí)例。記住,普通方法和原型都返回一個(gè) romise,這使得理解事物變得容易得多。

原型方法(Prototype Methods)

讓我們首先從原型方法開始,有三種方法。重申一下,記住所有這些方法都可以應(yīng)用于 Promise 對象的一個(gè)實(shí)例,并且所有這些方法依次返回一個(gè) Promise。以下所有方法都為 promise 的不同狀態(tài)轉(zhuǎn)換分配處理程序。正如我們前面看到的,當(dāng)創(chuàng)建一個(gè) Promise 時(shí),它處于 pending 狀態(tài)。Promise 根據(jù)是否 fulfilled(已成功)或rejected(已失?。?,將運(yùn)行以下三種方法中的一種或多種。

Promise.prototype.catch(onRejected)

Promise.prototype.then(onFulfilled, onRejected)

Promise.prototype.finally(onFinally)

下圖顯示了 then 和 .catch 方法的流程。由于它們返回一個(gè) Promise ,它們可以再次被鏈?zhǔn)秸{(diào)用。不管 promise 最后的狀態(tài),在執(zhí)行完t hen 或 catch 指定的回調(diào)函數(shù)以后,都會(huì)執(zhí)行finally方法指定的回調(diào)函數(shù)。

這里有一個(gè)小故事。你是一個(gè)上學(xué)的孩子,你問你的媽媽要一個(gè)電話。她說:“這個(gè)月底我要買一部手機(jī)?!?/p>

讓我們看看,如果承諾在月底執(zhí)行,JavaScript中會(huì)是什么樣子。

var momsPromise = new Promise(function(resolve, reject) {
  momsSavings = 20000;
  priceOfPhone = 60000;
  if (momsSavings > priceOfPhone) {
    resolve({
      brand: "iphone",
      model: "6s"
    });
  } else {
    reject("我們沒有足夠的儲(chǔ)蓄,讓我們多存點(diǎn)錢吧。");
  }
});
momsPromise.then(function(value) {
  console.log("哇,我得到這個(gè)電話作為禮物 ", JSON.stringify(value));
});
momsPromise.catch(function(reason) {
  console.log("媽媽不能給我買電話,因?yàn)?", reason);
});
momsPromise.finally(function() {
  console.log(
    "不管媽媽能不能給我買個(gè)電話,我仍然愛她"
  );
});

輸出:

如果我們把媽媽的禮物價(jià)值改為20萬美元,那么媽媽就可以給兒子買禮物了。在這種情況下,輸出將是

接著 then方法的第一個(gè)參數(shù)是 resolved 狀態(tài)的回調(diào)函數(shù),第二個(gè)參數(shù)(可選)是 rejected 狀態(tài)的回調(diào)函數(shù)。所以我們也可以這樣寫:

但是為了代碼的可讀性,我認(rèn)為最好將它們分開。

為了確保我們可以在瀏覽器中運(yùn)行所有這些示例,或者在chrome中運(yùn)行特定的示例,我要確保我們的代碼示例中沒有外部依賴關(guān)系。

為了更好地理解進(jìn)一步的主題,讓我們創(chuàng)建一個(gè)函數(shù),該函數(shù)將返回一個(gè) Promise,函數(shù)里隨機(jī)執(zhí)行 resolve 或者 rejected ,以便我們可以測試各種場景。

由于我們需要隨機(jī)數(shù),讓我們先創(chuàng)建一個(gè)隨機(jī)函數(shù),它將返回x和y之間的隨機(jī)數(shù)。

讓我們創(chuàng)建一個(gè)函數(shù),它將為我們返回 promise。讓我們調(diào)用 promiseTRRARNOSG 函數(shù),它是promiseThatResolvesRandomlyAfterRandomNumnberOfSecondsGenerator 的別名。這個(gè)函數(shù)將創(chuàng)建一個(gè) promise,該 promise 將在 2 到 10 秒之間的隨機(jī)數(shù)秒后執(zhí)行 resolve 或 reject。為了隨機(jī)執(zhí)行resolve 和 reject,我們將創(chuàng)建一個(gè)介于 1 和 10 之間的隨機(jī)數(shù)。如果生成的隨機(jī)數(shù)大于 5,我們將執(zhí)行 resolve ,否則執(zhí)行 reject。

function getRandomNumber(start = 1, end = 10) {
  //works when both start and end are >=1
  return (parseInt(Math.random() * end) % (end - start + 1)) + start;
}
var promiseTRRARNOSG = (promiseThatResolvesRandomlyAfterRandomNumnberOfSecondsGenerator = function() {
  return new Promise(function(resolve, reject) {
    let randomNumberOfSeconds = getRandomNumber(2, 10);
    setTimeout(function() {
      let randomiseResolving = getRandomNumber(1, 10);
      if (randomiseResolving > 5) {
        resolve({
          randomNumberOfSeconds: randomNumberOfSeconds,
          randomiseResolving: randomiseResolving
        });
      } else {
        reject({
          randomNumberOfSeconds: randomNumberOfSeconds,
          randomiseResolving: randomiseResolving
        });
      }
    }, randomNumberOfSeconds * 1000);
  });
});
var testProimse = promiseTRRARNOSG();
testProimse.then(function(value) {
  console.log("Value when promise is resolved : ", value);
});
testProimse.catch(function(reason) {
  console.log("Reason when promise is rejected : ", reason);
});
// 創(chuàng)建10個(gè)不同的promise
for (i=1; i<=10; i++) {
  let promise = promiseTRRARNOSG();
  promise.then(function(value) {
    console.log("Value when promise is resolved : ", value);
  });
  promise.catch(function(reason) {
    console.log("Reason when promise is rejected : ", reason);
  });
}

刷新瀏覽器頁面并在控制臺(tái)中運(yùn)行代碼,以查看resolve 和 reject 場景的不同輸出。

靜態(tài)方法

Promise對象中有四種靜態(tài)方法。

前兩個(gè)是幫助方法或快捷方式。 它們可以幫助您輕松創(chuàng)建 resolved 和 reject 方法。

Promise.reject(reason)

粟子:

Promise.resolve(value)

粟子:

在旁注上,promise 可以有多個(gè)處理程序。因此,你可以將上述代碼更新為:

輸出:

下面兩個(gè)方法幫助你處理一組 promise 。當(dāng)你處理多個(gè)promise 時(shí),最好先創(chuàng)建一個(gè)promise 數(shù)組,然后對這些promise 集執(zhí)行必要的操作。

為了理解這些方法,我們不能使用上例中的 promiseTRRARNOSG,因?yàn)樗S機(jī)了,最好有一些確定性的 promise ,這樣我們才能更好理解 promise 行為。

讓我們創(chuàng)建兩個(gè)函數(shù)。一個(gè)會(huì)在n秒后執(zhí)行resolve,另一個(gè)會(huì)在n秒后執(zhí)行 reject。

現(xiàn)在讓我們使用這些幫助函數(shù)來理解 Promise.All

Promise.All

根據(jù) MDN 文檔:

Promise.all(iterable) 方法返回一個(gè) Promise 實(shí)例,此實(shí)例在 iterable 參數(shù)內(nèi)所有的 promise
都“完成(resolved)”或參數(shù)中不包含 promise 時(shí)回調(diào)完成(resolve);如果參數(shù)中 promise
有一個(gè)失?。╮ejected),此實(shí)例回調(diào)失敗(reject),失敗原因的是第一個(gè)失敗 promise 的結(jié)果。

例一:當(dāng)所有的 promise 都執(zhí)行完成了,這是最常用的場景。

我們需要從輸出中得出兩個(gè)重要的結(jié)論:

第三個(gè) promise 需要2秒完成,第二個(gè) promise 需要4秒。但是正如你在輸出中看到的,promise
的順序在值中保持不變。

我添加了一個(gè)計(jì)時(shí)器來確定 promise 執(zhí)行所需要時(shí)間。如果 promise 是按順序執(zhí)行的,那么總共需要 1+4+2=7 秒,但是從計(jì)時(shí)器中我們看到它只需要4秒。這證明了所有的 promise 都是并行執(zhí)行的。

例二:當(dāng)數(shù)組不是 promise 的時(shí)候呢?(我認(rèn)為這是最不常用的)

輸出:

由于數(shù)組中沒有 promise,因此將執(zhí)行 promise 中的 resolve。

例一:其中一個(gè) promise 狀態(tài)最先為 resolve 狀態(tài)

Promise.race

根據(jù) MDN:

Promise.race(iterable) 方法返回一個(gè) promise,一旦迭代器中的某個(gè)promise解決或拒絕,返回的 promise就會(huì)解決或拒絕。
const p = Promise.race([p1, p2, p3]);

上面代碼中,只要p1、p2、p3之中有一個(gè)實(shí)例率先改變狀態(tài),p的狀態(tài)就跟著改變。那個(gè)率先改變的 Promise 實(shí)例的返回值,就傳遞給 p 的回調(diào)函數(shù)。

所有的 promise 都是并行運(yùn)行的。第三個(gè) promise 在 2 秒內(nèi)完成,所以是最先改變的就返回給Promise.race。

例二:其中一個(gè) promise 狀態(tài)最先為 reject 狀態(tài)

所有的 promise 都是并行運(yùn)行的。第四個(gè) promise 在 3 秒內(nèi)完成,所以是最先改變的就返回給Promise.race。

使用 promise 的經(jīng)驗(yàn)法則

使用異步或阻塞代碼時(shí),請使用 promise。

為了代碼的可讀性,resolve 方法對待 then, reject 對應(yīng) catch 。

確保同時(shí)寫入.catch 和 .then 方法來實(shí)現(xiàn)所有的 promise。

如果在這兩種情況下都需要做一些事情,請使用 .finally。

我們只有一次改變每個(gè)promise (單一原則)。

我們可以在一個(gè)promise 中添加多個(gè)處理程序。

Promise對象中所有方法的返回類型,無論是靜態(tài)方法還是原型方法,都是Promise。

在Promise.all中,無論哪個(gè)promise 首先未完成,promise 的順序都保持在值變量中。

原文:https://hackernoon.com/unders...

你的點(diǎn)贊是我持續(xù)分享好東西的動(dòng)力,歡迎點(diǎn)贊!

一個(gè)笨笨的碼農(nóng),我的世界只能終身學(xué)習(xí)!

交流

干貨系列文章匯總?cè)缦?,覺得不錯(cuò)點(diǎn)個(gè)Star,歡迎 加群 互相學(xué)習(xí)。

https://github.com/qq44924588...

我是小智,公眾號「大遷世界」作者,對前端技術(shù)保持學(xué)習(xí)愛好者。我會(huì)經(jīng)常分享自己所學(xué)所看的干貨,在進(jìn)階的路上,共勉!

關(guān)注公眾號,后臺(tái)回復(fù)福利,即可看到福利,你懂的。

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

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/53419.html

相關(guān)文章

  • JavaScript 異步

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。寫一個(gè)符合規(guī)范并可配合使用的寫一個(gè)符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個(gè)需求:在系統(tǒng)初始化時(shí)通過http獲取一個(gè)第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個(gè)接口,可通過...

    tuniutech 評論0 收藏0
  • ES6-7

    摘要:的翻譯文檔由的維護(hù)很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會(huì)promise...... 本書的目的是以目前還在制定中的ECMASc...

    mudiyouyou 評論0 收藏0
  • 理解 Javascript 中的 Promise

    摘要:理解承諾有兩個(gè)部分。如果異步操作成功,則通過的創(chuàng)建者調(diào)用函數(shù)返回預(yù)期結(jié)果,同樣,如果出現(xiàn)意外錯(cuò)誤,則通過調(diào)用函數(shù)傳遞錯(cuò)誤具體信息。這將與理解對象密切相關(guān)。這個(gè)函數(shù)將創(chuàng)建一個(gè),該將在到秒之間的隨機(jī)數(shù)秒后執(zhí)行或。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! showImg(https://segmentfault.com/img/bVbkNvF?w=1280&h=...

    paulli3 評論0 收藏0
  • 理解javascript中的事件循環(huán)(Event Loop)

    摘要:主線程會(huì)暫時(shí)存儲(chǔ)等異步操作,直接向下執(zhí)行,當(dāng)某個(gè)異步事件觸發(fā)時(shí),再通知主線程執(zhí)行相應(yīng)的回調(diào)函數(shù),通過這種機(jī)制,避免了單線程中異步操作耗時(shí)對后續(xù)任務(wù)的影響。 背景 在研究js的異步的實(shí)現(xiàn)方式的時(shí)候,發(fā)現(xiàn)了JavaScript 中的 macrotask 和 microtask 的概念。在查閱了一番資料之后,對其中的執(zhí)行機(jī)制有所了解,下面整理出來,希望可以幫助更多人。 先了解一下js的任務(wù)執(zhí)...

    mykurisu 評論0 收藏0
  • 理解異步JavaScript

    摘要:當(dāng)函數(shù)結(jié)束,將會(huì)被從調(diào)用棧移出。事件循環(huán)事件循環(huán)的責(zé)任就是查看調(diào)用棧并確定調(diào)用棧是否為空。事件循環(huán)會(huì)再次檢查調(diào)用棧是否為空,如果為空的話,它會(huì)把事件回調(diào)壓入棧中,然后回調(diào)函數(shù)則被執(zhí)行。 寫在文章前 這篇文章是翻譯自Sukhjinder Arora的Understanding Asynchronous JavaScript。這篇文章描述了異步和同步JavaScript是如何在運(yùn)行環(huán)境中,...

    ixlei 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<