理解koa2 之 async + await + promise


koa是下一代的Node.js web框架。

我們首先使用koa來實現一個簡單的hello world吧!假如目前的項目結構如下:

### 目錄結構如下:
koa-demo1                              # 工程名
|  |--- app.js                         # node 入口文件
|  |--- node_modules                   # 項目依賴包
|  |--- package.json

app.js 代碼如下:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  console.log(ctx);
  await next();
  ctx.response.type = 'text/html';
  ctx.response.body = 'hello world';
});

app.listen(3001);
console.log('app started at port 3001...');

如上,對於頁面中每一個http請求,koa將調用如上異步函數來處理。進入項目中的根目錄執行 node app.js 后,在頁面中訪問 http://localhost:3001/ 后刷新看到node控制台打印 console.log(ctx); 如下信息:

參數ctx是koa傳入封裝的了request和response的變量,如上圖可以看到,我們就可以通過ctx來訪問request和response的數據了,我們可以再看下瀏覽器中 header信息如下,我們可以對比下 上面圖和下面的圖:

並且我們在看看瀏覽器中網絡請求可以看到有如下兩條請求,在node中也可以看到打印了二次,說明對於頁面中每一個http請求,koa將調用如上異步函數來處理的,如下所示:

如上的代碼異步函數中,使用了 await next();來處理下一個異步函數,和express中的 next()方法類似的功能,然后設置 response的Content-Type的內容。

async的理解為:用於聲明一個function是異步的,並且返回的是一個promise對象,如下代碼:

async function testAsync() {
  return 'hello world';
}

const a = testAsync();

console.log(a);

在瀏覽器中打印如下:

await的含義是:用於等待一個異步方法執行完成(同步等待)。

await在等待async異步方法執行完畢,await必須在async方法中才可以使用。

如下代碼demo理解:

function getData () {
  return 'hello world';
}

async function testAsync() {
  return 'hello xxxx';
}

async function testAsync2() {
  const a1 = await testAsync();
  const a2 = await getData();
  console.log(a1); // hello xxxx
  console.log(a2); // hello world
}

testAsync2();

如上代碼 getData是同步方法,testAsync是異步方法的,都會返回一條信息,但是在testAsync2異步方法內部,都使用await 使數據同步返回,因此結果打印: hello xxxx;和 hello world了。

但是如果我們在 testAsync2 函數內部不使用 await 這個,直接調用 testAsync()方法和getData()方法的話,那么testAsync就會返回一個promise對象了,如下代碼:

function getData () {
  return 'hello world';
}

async function testAsync() {
  return 'hello xxxx';
}

function testAsync2() {
  const a1 = testAsync();
  const a2 = getData();
  
  console.log(a1); 
  console.log(a2); 
}

testAsync2();

執行結果如下所示:

1. async的作用是?

async函數它會返回一個promise對象,我們可以通過promise對象的then方法來獲取如上的 'hello world' 的值,如下代碼所示:

async function testAsync() {
  return 'hello xxxx';
}

const test = testAsync();

console.log(test); // Promise {<resolved>: "hello xxxx"}

test.then(data => {
  console.log(data);  // 打印 hello xxxx
});

2. await的作用是?

await可以理解為同步等待當前的async的執行,且等async后的promise對象執行resolve,然后拿到resolve的值,作為await表達式的運算結果。代碼才會繼續往下執行。

我們可以看如下demo來理解下:

function testA() {
  return 'hello world';
}

async function testA2() {
  return 'xxxx';
}

async function testA3() {
  // 等待返回 'heelo world'
  const a1 = await testA();

  // 待會返回promise對象的resolve的值,才會繼續往下執行
  const a2 = await testA2();

  console.log(a1 + '--' + a2); // 會打印 hello world--xxxx
}

testA3(); 

3. async + await + promise 解決異步問題

如下基本的代碼:

let url = 'xxxxx'; // url 地址
let asyncFn = async () => {
  let data = null;
  data = await getData(url);
  console.log(data);
}

const getData = function(url) {
  return new Promise((resolve, reject) => {
    // 如下簡單的使用 ajax來演示下,項目中具體使用fetch還是其他都可以的
    $.ajax({
      type: 'get',
      dataType: 'json',
      data: {
        
      },
      success: function(d) {
        resolve(d);
      },
      error: function(e) {
        reject(e);
      }
    })
  });
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM