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

資訊專欄INFORMATION COLUMN

Promise之深入淺出

littleGrow / 1888人閱讀

摘要:不兼容問題,本文不予以處理,出門左轉,找谷哥。如果中的回調(diào)函數(shù)拋出一個錯誤,那么返回的將會成為拒絕狀態(tài),并且將拋出的錯誤作為拒絕狀態(tài)的回調(diào)函數(shù)的參數(shù)值。

Promise與async

主要內(nèi)容:

promise基本實現(xiàn)原理

promise 使用中難點(鏈式調(diào)用,API基本上返回都是一個新Promise,及參數(shù)傳遞)

promise 對異常處理

參考:

? 30分鐘,讓你徹底明白Promise原理

? 阮一峰ES6入門

? JavaScript Promise:簡介

0. 基本用法

基本的promise使用

1. 兼容性

查看caniuse

查兼容性 基本上 主流瀏覽器支持沒有問題。

IE不兼容 問題,本文不予以處理,出門左轉,找谷哥。具體查看 babel,或者 自己實現(xiàn)一個Promise

2. ajax XMLHttpRequest封裝
//get 請求封裝
function get(url) {
  // Return a new promise.
  return new Promise(function(resolve, reject) {
    // Do the usual XHR stuff
    var req = new XMLHttpRequest();
    req.open("GET", url);

    req.onload = function() {
      // This is called even on 404 etc
      // so check the status
      if (req.status == 200) {
        // Resolve the promise with the response text
        resolve(req.response);
      }
      else {
        // Otherwise reject with the status text
        // which will hopefully be a meaningful error
        reject(Error(req.statusText));
      }
    };

    // Handle network errors
    req.onerror = function() {
      reject(Error("Network Error"));
    };

    // Make the request
    req.send();
  });
}
1. Promse API

Promise API 分為 :MDN

靜態(tài)方法

prototype上方法

Promise.prototype.then() 來分析

首先來看看 Promise.prototype.then()返回一個Promise,但Promise內(nèi)部有返回值,且 返回值,可以是個值,也可能就是一個新Promise

   *具體規(guī)則如下:*

- *如果then中的回調(diào)函數(shù)返回一個值,那么then返回的Promise將會成為接受狀態(tài),并且將返回的值作為接受狀態(tài)的回調(diào)函數(shù)的參數(shù)值。*
- *如果then中的回調(diào)函數(shù)拋出一個錯誤,那么then返回的Promise將會成為拒絕狀態(tài),并且將拋出的錯誤作為拒絕狀態(tài)的回調(diào)函數(shù)的參數(shù)值。*
- *如果then中的回調(diào)函數(shù)返回一個已經(jīng)是接受狀態(tài)的Promise,那么then返回的Promise也會成為接受狀態(tài),并且將那個Promise的接受狀態(tài)的回調(diào)函數(shù)的參數(shù)值作為該被返回的Promise的接受狀態(tài)回調(diào)函數(shù)的參數(shù)值。*
- *如果then中的回調(diào)函數(shù)返回一個已經(jīng)是拒絕狀態(tài)的Promise,那么then返回的Promise也會成為拒絕狀態(tài),并且將那個Promise的拒絕狀態(tài)的回調(diào)函數(shù)的參數(shù)值作為該被返回的Promise的拒絕狀態(tài)回調(diào)函數(shù)的參數(shù)值。*
- *如果then中的回調(diào)函數(shù)返回一個未定狀態(tài)(pending)的Promise,那么then返回Promise的狀態(tài)也是未定的,并且它的終態(tài)與那個Promise的終態(tài)相同;同時,它變?yōu)榻K態(tài)時調(diào)用的回調(diào)函數(shù)參數(shù)與那個Promise變?yōu)榻K態(tài)時的回調(diào)函數(shù)的參數(shù)是相同的。*

上面是官方規(guī)則,神馬,具體白話就是 核心是 返回參數(shù)及返回promise的狀態(tài)

參考:MDN

是不是 覺得很暈,沒關系,可以先看 下一節(jié),看完后,再回過來看具體的說明
2. Prmise 鏈式調(diào)用

鏈式調(diào)用

 1.  核心就是 then catch 等方法返回一個Promise
2.  鏈式 調(diào)用數(shù)據(jù)傳遞(注意)
1. 值傳遞問題

簡單例子

//正常狀態(tài)
const promise1 = new Promise((resolve, reject) => {
    resolve("0000")//
})
promise1.then(result => {
    console.log(result) //0000
       return "1111";//類似于 return Promise.resolve("1111"); 參數(shù)是data,promise 狀態(tài)時 resolve
}).then(data => {
    console.log(data) // 1111
})

一個實際的例子:(拿來大神的例子JavaScript Promise:簡介)

get("story.json").then(function(response) {
  console.log("Success!", response);
})
//這里的 response 是 JSON,但是我們當前收到的是其純文本。也可以設置XMLHttpRequest.responseType =json
get("story.json").then(function(response) {
  return JSON.parse(response);
}).then(function(response) {
  console.log("Yey JSON!", response);
})
//由于 JSON.parse() 采用單一參數(shù)并返回改變的值,因此我們可以將其簡化為:
get("story.json").then(JSON.parse).then(function(response) {
  console.log("Yey JSON!", response);
})
function getJSON(url) {
  return get(url).then(JSON.parse);
}
//getJSON() 仍返回一個 promise,該 promise 獲取 URL 后將 response 解析為 JSON。
2. 異步操作隊列

上面至今是return 值 ,直接調(diào)用 下一下then就OK了。

但如果return Promise,則?

Promise.resolve(111).then(function(d){
    console.log(d);
    return Promise.resolve(d+111);//返回promise
}).then(function(d2){
    console.log(d2);
})
// 111,222
3. 基本實現(xiàn)原理

主要是 如何自己實現(xiàn)一個簡單的Promise

//極簡實現(xiàn)
function Promise(fn) {
    var value = null,
        callbacks = [];  //callbacks為數(shù)組,因為可能同時有很多個回調(diào)

    this.then = function (onFulfilled) {
        callbacks.push(onFulfilled);
    };

    function resolve(value) {
        callbacks.forEach(function (callback) {
            callback(value);
        });
    }

    fn(resolve);
}
4. finnaly 實現(xiàn)
Promise.prototype.finally = function (callback) {
  let P = this.constructor;
  return this.then(
    value  => P.resolve(callback()).then(() => value),
    reason => P.resolve(callback()).then(() => { throw reason })
  );
};
5. 異常處理

異常分類:

同步異常

異步異常 無法try-catch 得到

多層Promise嵌套,獲異常取具體的一個promise異常,而不是全部

1. Promise 異常處理基本套路

基本處理異常中,有兩種方案then(undefined, func)catch()

then(undefined, func)catch()不同,具體參見代碼方案3

//方案1 使用 Promise.prototype.catch()來catch
const promise1 = new Promise((resolve, reject) => {
    reject("no")// 
})
promise1.then(result => {
    console.log(result) // 永遠不會執(zhí)行
}).catch(error => {
    console.log(error) // no
})
//方案2 使用 Promise.prototype.then()中第二個參數(shù) 來處理
const promise1 = new Promise((resolve, reject) => {
    reject("no")// 
})
promise1.then(result => {
    console.log(result) // 永遠不會執(zhí)行
},error => {
    console.log(error) // no
})
//方案2  (方案1  方案2 對比)
var promise2 = new Promise((resolve, reject) => {
    resolve("yes")// 
})
promise2.then(result => {
    throw new Error("then");
    console.log(result) 
},error => {
    console.log("1111",error) // no
}).catch(error=>{
   console.log("2222",error)// 最終 err在此處被捕獲,而不是 then 中
})
2. 異常不同分類

Promise可能遇到的異常種類

//1.異常 reject()
const promise1 = new Promise((resolve, reject) => {
    reject("no")// 
})
promise1.then(result => {
    console.log(result) // 永遠不會執(zhí)行
}).catch(error => {
    console.log(error) // no
})
//2.異常 顯示throw
const promise1 = new Promise((resolve, reject) => {
    throw Error("no")
})
promise1.then(result => {
    console.log(result) // 永遠不會執(zhí)行
}).catch(error => {
    console.log(error) // 
})
//3.執(zhí)行異常
const promise1 = new Promise((resolve, reject) => {
    aaaa;
})
promise1.then(result => {
    console.log(result) // 永遠不會執(zhí)行
}).catch(error => {
    console.log(error) // 
})
3. 異常鏈式調(diào)用
asyncThing1().then(function() {
  return asyncThing2();
}).then(function() {
  return asyncThing3();
}).catch(function(err) {
  return asyncRecovery1();
}).then(function() {
  return asyncThing4();
}, function(err) {
  return asyncRecovery2();
}).catch(function(err) {
  console.log("Don"t worry about it");
}).then(function() {
  console.log("All done!");
})

上述代碼的流程圖形式:

流程圖形式

// promise鏈式調(diào)用,catch住異常后,后面就不會處理異常了
Promise.reject().then(()=>{
  console.log(2222);
},(err)=>{
    console.log(333,err)
    return err})
.catch((err)=>{
  console.log(1111,err);
})
//333 undefined  ,沒有打印 1111
//如果 在鏈式調(diào)用中,then 第二個參數(shù) catch住了異常,沒有return Promise.reject()則后續(xù)鏈式調(diào)用返回rosolve狀態(tài)pormise
Promise.reject()
   .then(()=>{
      console.log(111);
    },(err)=>{
        console.log(111,err) //reject 
        return err;
    }).then((data)=>{
        console.log(222,data);//resolve 執(zhí)行
    },(err)=>{
      console.log(222,err); //未執(zhí)行
    })
//4444 沒有執(zhí)行 1111
4. 異常丟失

很多情況下,promise無法捕獲異常

場景1 macrotask 隊列中拋出異常:

//場景1
//永遠不要在 macrotask 隊列中拋出異常,因為 macrotask 隊列脫離了運行上下文環(huán)境,異常無法被當前作用域捕獲。
function fetch(callback) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
             throw Error("用戶不存在")
        })
    })
}

fetch().then(result => {
    console.log("請求處理", result) // 永遠不會執(zhí)行
}).catch(error => {
    console.log("請求處理異常", error) // 永遠不會執(zhí)行
})

// 程序崩潰
// Uncaught Error: 用戶不存在

/*
    參考
    作者:黃子毅
    鏈接:https://www.jianshu.com/p/78dfb38ac3d7
    來源:簡書
    簡書著作權歸作者所有,任何形式的轉載都請聯(lián)系作者獲得授權并注明出處。
*/
//解決場景1 怎么解決,因為setTimeout 是macrotask任務,執(zhí)行上下文完全不同
/**
    如何解決?
    調(diào)用reject
*/
function fetch() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject("收斂一些")
        })
    })
}
fetch().then((resolve, reject) => {
    console.log("resolve");
}).catch(error => {
    console.log("捕獲異常", error) // 捕獲異常 收斂一些
})

場景二 Promise 狀態(tài)只能改變一次

 //異常丟失
   const promise2 = new Promise((resolve, reject) => {
       reject("no")
       console.log("reject after")
     throw Error("no") //異常丟失
   })
   promise1.then(result => {
       console.log(result) // 永遠不會執(zhí)行
   }).catch(error => {
       console.log("err",error) // no
   }).catch(error => {
       console.log("err2",error) // 也無法捕獲異常
   })
6.async

基本語法

function timeout(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

async function asyncPrint(value, ms) {
  await timeout(ms);
  console.log(value);
  return value;   //類似 return Promise.resolve(value)
}
//async 返回一個promise
asyncPrint("hello world", 50).then(function(d){
   console.log("then",d);
});
/** 打印
hello world
then hello world
*/

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

轉載請注明本文地址:http://m.hztianpu.com/yun/98156.html

相關文章

  • es6深入理解promise

    摘要:形式非必須,也非必須調(diào)用把用函數(shù)表示在調(diào)用的時候用函數(shù)代碼更加同步化三是什么異步操作的終極解決方案寫法四總結不管用還是用還是用,都保證你寫的的返回值是一個對象 一、promise入門 1. Promise對象是什么 回調(diào)函數(shù)的另一種原生實現(xiàn),比之前回調(diào)函數(shù)的寫法機構清晰,功能強大, 2.以前回調(diào)這么寫 function a(fn){ let h = 1; setTime...

    luckyw 評論0 收藏0
  • 深入探析koa異步回調(diào)處理篇

    摘要:而之后,我們得到的是一個是一個對象,我們可以使用語句定義回調(diào)函數(shù),函數(shù)的內(nèi)容呢,則是將讀取到的返回給并繼續(xù)讓從斷點處執(zhí)行。 在上一篇中我們梳理了koa當中中間件的洋蔥模型執(zhí)行原理,并實現(xiàn)了一個可以讓洋蔥模型自動跑起來的流程管理函數(shù)。這一篇,我們再來研究一下koa當中異步回調(diào)同步化寫法的原理,同樣的,我們也會實現(xiàn)一個管理函數(shù),是的我們能夠通過同步化的寫法來寫異步回調(diào)函數(shù)。 1. 回調(diào)金字...

    Drinkey 評論0 收藏0
  • ES6-7

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

    mudiyouyou 評論0 收藏0
  • 再談Promise

    摘要:方法完成回調(diào)注冊模式下,對象通過方法調(diào)用,注冊完成態(tài)和失敗態(tài)的回調(diào)函數(shù)。這些回調(diào)函數(shù)組成一個回調(diào)隊列,處理的值。調(diào)用實例的方法,能使注冊的回調(diào)隊列中的回調(diào)函數(shù)依次執(zhí)行。 之前寫了一篇關于ES6原生Promise的文章。近期又讀樸靈的《深入淺出Node》,里面介紹了一個Promise/Deferred模式。 Promise是解決異步問題的利器。它其實是一種模式。Promise有三種狀態(tài),...

    chenjiang3 評論0 收藏0
  • JavaScript 異步編程的四種方式

    摘要:異步編程是每個使用編程的人都會遇到的問題,無論是前端的請求,或是的各種異步。本文就來總結一下常見的四種處理異步編程的方法。利用一種鏈式調(diào)用的方法來組織異步代碼,可以將原來以回調(diào)函數(shù)形式調(diào)用的代碼改為鏈式調(diào)用。 異步編程是每個使用 JavaScript 編程的人都會遇到的問題,無論是前端的 ajax 請求,或是 node 的各種異步 API。本文就來總結一下常見的四種處理異步編程的方法。...

    microelec 評論0 收藏0

發(fā)表評論

0條評論

littleGrow

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<