1. 程式人生 > >關於Promise與async/await的例子

關於Promise與async/await的例子

今天不想寫太多的文字,就來兩段程式碼吧,我今天最有用的收穫應該就是在這程式碼中,下面我就將它們分享出來

程式碼片段一

var p = Promise.resolve();

var ret = null;
console.log("outer1");

var ary = [23, 34, 45, 56, 67];
for(var i of ary) {
  console.log("test-for" , i);
  p = p.then(function(val) {
    console.log("test-promise" , i);
    console.log(val);
    return
val; }); } console.log("outer2");

你完全可以把上面的程式碼放在控制檯下執行,當然瀏覽器得支援Promise

下面看下結果:

這裡寫圖片描述

這個結果你想到了嗎?我就來解析一下,JS的程式碼的執行順序是自上而下的(參考這裡),所以我想outer1, test-for 一直到outer2這部分的輸出你應該是可以看懂的,當然我知道你此時是有疑問的,then是屬於非同步操作的所以每次都會將它放入一個非同步佇列中,所以這部分是最後執行的,所以之後才會出現test-promise這些輸出,then裡面的第一個引數就是onFulfilled狀態下呼叫的函式,這個函式中引用了i

這個變數,但是會發先它的輸出都是5,要知道在同步部分執行結束之後,i的值就是5,所以輸出5也是沒得說的

關於為什麼輸出val的值都是undefined呢?

這次就需要你對著程式碼看這段話了,首先第一行Promise.resolve()執行之後,會返回一個Promise物件,也就是說此時的p就是一個Promise物件,而執行完p.then(...)之後會返回一個新的Promise物件,現在我打算將這個Promise物件“晾出來”給你看看,如下,這個Promise是執行完Promise.resolve()所產生的。

這裡寫圖片描述

我順便也將其他的Promise也輸出了,當然是和上面一樣的,但是請注意,它們真的不是同一個Promise。

下面正式解釋 為什麼輸出了”undefined”

Promise.resolve()相當於下面的程式碼

new Promise(function(resolve, reject) {
  resolve();
})

關於then部分的程式碼,其實可以看成是這樣的

new Promise(function(resolve, reject) {
  resolve();
}).then(function(val) {
    return val;
}).then(function(val) {
    //同上
}).then(function(val) {
    //同上
}).then(function(val) {
    //同上
}).then(function(val) {
    //同上
});

呼叫resolve的時候,並沒有傳遞引數,所以第一個形參val的值就是undefined,因為存在return,所以第二個形參val的值就是undefined,其他的同理可得

程式碼片段二

在看下面的程式碼之前,你可以先去了解一下,fetch(參考這裡)、async/await(參考這裡

分成兩部分來看吧,下面是第一個部分

async function logInOrder(urls) {
  for (const url of urls) {
    const response = await fetch(url);
    console.log(await response.text());
  }
}
logInOrder(['https://httpbin.org/get', 'https://azu.github.io/promises-book/json/comment.json']);

如果你看了需要了解的東西或者說你之前就有所瞭解,那麼我想上面的程式碼的輸出結果你大致可以知道它們輸出的是什麼

下面就是第二部分,也是我今天收穫的地方

function toPromise(n) {
  return new Promise((resolve) => {
    resolve(n);
  })
}

async function test(data) {
  for(const n of data) {
    console.log(await toPromise(n));  //這個輸出語句在之後我會進行變動
  }
}

test([1, 3, 5, 7, 8]); 

輸出結果是:

1 3 5 7 8

當時我就比較好奇,為什麼會是這樣的呢?然後又進行了下面的輸出

console.log(toPromise(n));

輸出結果如下:

這裡寫圖片描述

看到這裡有沒有發現,不加await的時候返回的就是一個Promsie物件,而加上await返回的值和Promise中的[[PromiseValue]]的值是一樣的,“await命令就是內部then命令的語法糖”,現在我看到的就是await會將一個Promise物件的PromiseValue返回

如果你看到我寫的Fetch那篇部落格了,你就應該知道Fetch是基於Promise實現的,所以,我又特地將第一部分的程式碼進行了修改,其實也就是加了一句輸出

async function logInOrder(urls) {
  for (const url of urls) {
    console.log(fetch(url));
    const response = await fetch(url);
    console.log(await response.text());
  }
}
logInOrder(['https://httpbin.org/get', 'https://azu.github.io/promises-book/json/comment.json']);

輸出結果如下:

這裡寫圖片描述

所以也就說明了Fetch(url)的返回值就是一個Promise物件,所以也就是基於Promise的了

然後,我又將第一部分的程式碼進行了修改

async function logInOrder(urls) {
  for (const url of urls) {
    console.log(fetch(await fetch(url)));
  }
}
logInOrder(['https://httpbin.org/get', 'https://azu.github.io/promises-book/json/comment.json']);

輸出結果如下:

這裡寫圖片描述

有沒有發現,加上await的輸出和fetch(url)獲得的Promise物件的[[PromisValue]]的值是一樣的

目前我的理解就是上面那些,歡迎交流,也歡迎指出我的不足