Node.js 教程第六篇——Async

DK_Lan發表於2019-02-16

Async

Node.js 是一個非同步機制的服務端語言,在大量非同步的場景下需要按順序執行,那正常做法就是回撥巢狀回撥,回撥巢狀太多的問題被稱之回撥地獄。

Node.js 為解決這一問題推出了非同步控制流 ———— Async

Async/Await

Async/Await 就 ES7 的方案,結合 ES6 的 Promise 物件,使用前請確定 Node.js 的版本是 7.6 以上。

Async/await的主要益處是可以避免回撥地獄(callback hell),且以最接近同步程式碼的方式編寫非同步程式碼。

基本規則

  • async 表示這是一個async函式,await只能用在這個函式裡面。
  • await 表示在這裡等待promise返回結果了,再繼續執行。
  • await 後面跟著的應該是一個promise物件

對比使用

場景:3秒後返回一個值

原始時代

let sleep = (time, cb) => {
    setTimeout(() => {
        cb(`ok`);
    }, 3000);
}

let start = () => {
    sleep(3000, (result) => {
        console.log(result)
    })
}

start()

Promise 時代

let sleep = (time) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
           resolve(`ok`) ;
        }, time);
    })
}

let start = () => {
    sleep(3000).then((result) => {
        console.log(result)
    })
}

start()

Async/Await 時代

let sleep = (time) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
           resolve(`ok`) ;
        }, time);
    })
}

let start = async () => {
    let result = await sleep(3000);
    console.log(result)
}

start();

捕捉錯誤

let sleep = (time) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject(`error`) ;
        }, time);
    })
}

let start = async () => {
    try{
        let result = await sleep(3000);
        console.log(result)
    } catch(err) {
        console.log(`error`)
    }
}

start();

在迴圈中使用

let sleep = (time) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(`ok`) ;
        }, time);
    })
}

let start = async () => {
    for (var i = 1; i <= 3; i++) {
        console.log(`當前是第${i}次等待..`);
        await sleep(1000);
    }
}

start();

爬蟲中使用

const request = require(`request`);
const fs = require(`fs`);
const cheerio = require(`cheerio`);

let spider = (url) => {
    return new Promise((resolve, reject) => {
        request(url, (error, response, body) => {
            resolve(body);
        })
    })
}

let start = async () => {
    let dom = await spider(`http://www.lanrentuku.com/`);
    let $ = cheerio.load(dom);
    $(`img`, `.in-ne`).each((i, e) => {
        let src = $(e).attr(`src`);
        let name = src.substr(src.lastIndexOf(`/`) + 1);
        request(src).pipe(fs.createWriteStream(name))
    })
}

start();

相關文章