通俗淺顯的理解promise中的then

文章原文出處:博主petruslaw

Promise,ES6中定義的規範,不會使用Promise,都不敢說自己用過ES6,大部分介紹Promise的規範的文章對於新手小白來說看得雲裏霧裏,且並不是通俗易懂。本文通過實例介紹講述Promise中then的的最通俗應用理解,代碼建立在不出現異常的情況的操作下,不嚴謹之處,請以官方規範爲標準。

先看一下下面4個Promise到底有什麼區別呢?

func().then(function () {
  return cb();
});
 
func().then(function () {
  cb();
});
 
func().then(cb());
 
func().then(cb);

如果你知道答案,以下內容你可以不用繼續。

上面的代碼過於簡單,運行時話需要稍微進行一點擴展,每個方法中都打印出promise上一步的調用值,爲了方便我給每個方法加了一個下標輸出,分別是1、2、3、4。

let func = function() {
    return new Promise((resolve, reject) => {
        resolve('返回值');
    });
        /*
    resolve和reject是函數,接收函數的函數是高階函數。此處的高階函數就是
    Promise()內部代碼整體(匿名箭頭函數)。      
    箭頭函數內部沒有this,其this指向箭頭函數的上一個臨近函數/對象。
	*/
};

	
let cb = function() {
    return '新的值';
}

func().then(function () {
    return cb();
}).then(resp => {
    console.warn(resp);
    console.warn('1 =========<');
});

func().then(function () {
    cb();
}).then(resp => {
    console.warn(resp);
    console.warn('2 =========<');
});

func().then(cb()).then(resp => {
    console.warn(resp);
    console.warn('3 =========<');
});

func().then(cb).then(resp => {
    console.warn(resp);
    console.warn('4 =========<');
});

不賣關子,直接看結果
在這裏插入圖片描述

首先要明白Promise中then方法會幹什麼事情!

官方文檔是這樣定義的:

一個 promise 必須提供一個 then 方法以訪問其當前值、終值和據因。
promise 的 then 方法接受兩個參數:

promise.then(onFulfilled, onRejected) Todo:這裏只介紹onFulfilled,所以刪除了關於onRejected的規範定義

onFulfilled 和 onRejected 都是可選參數。

如果 onFulfilled 不是函數,其必須被忽略
如果 onFulfilled 是函數:

當 promise 執行結束後其必須被調用,其第一個參數爲 promise 的終值
在 promise 執行結束前其不可被調用
其調用次數不可超過一次

用通(ren)俗(hua)的話來說:
then方法提供一個供自定義的回調函數,若傳入非函數,則會忽略當前then方法。
回調函數中會把上一個then中返回的值當做參數值供當前then方法調用。
then方法執行完畢後需要返回一個新的值給下一個then調用(沒有返回值默認使用undefined)。
每個then只可能使用前一個then的返回值。

直觀的圖:
在這裏插入圖片描述
有了上面的定義我們帶着三個疑問來回答問題:

  1. 上一個then中傳入了回調函數嗎?
  2. 上一個then中提供了返回值嗎?
  3. 若上一個then中若提供了返回值,返回了什麼?

執行第一個方法:

func().then(function () {
    return cb();
}).then(resp => {
    console.warn(resp);
    console.warn('1 =========<');
});

在這裏插入圖片描述

function () {
    return cb();
}

顯而易見,是傳入了回調函數的
回調函數中把cb執行後的返回值當做then中的返回值,所以輸出了“新的值”;

執行第二個方法:

func().then(function () {
    cb();
}).then(resp => {
    console.warn(resp);
    console.warn('2 =========<');
});

在這裏插入圖片描述

function () {
    cb();
}

then回調方法,只是執行了cb方法,並沒有return值,定義中講過若then沒有返回值,提供給下一個then使用的參數就是undefined,所以打印出來的是undefined;

執行第三個方法:

func().then(cb()).then(resp => {
    console.warn(resp);
    console.warn('3 =========<');
});

在這裏插入圖片描述
then中cb()執行後返回的並不是一個函數,在Promise規範中會自動忽略調當前then,所以會把func中的返回值供下一個then使用,輸出了“返回值”

執行第四個方法:

func().then(cb).then(resp => {
    console.warn(resp);
    console.warn('4 =========<');
});

在這裏插入圖片描述
第一個方法在回調內部返回cb執行後的值,第四個方法則直接把cb當做回調,第一個方法與第四個方法異曲同工之妙,所以也輸出了“新的值”。

題目出處:link
Promise規範:link

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章