1. 程式人生 > 其它 >回撥地獄

回撥地獄

回撥地獄

形如一下程式碼, 非同步函式不斷巢狀導致程式碼可讀性和可維護性大幅下降,這就是回撥地獄

    var fs = require('fs');
    
    fs.readFile('./doc/text.txt', (error, data) => {
        if (error)
            throw console.log('讀取檔案失敗', error);
        console.log('讀取檔案成功', data);

        fs.readFile('./doc/text1.txt', (error, data) => {
            if (error)
                throw console.log('讀取檔案失敗', error);
            console.log('讀取檔案成功', data);

            fs.readFile('./doc/text2.txt', (error, data) => {
                if (error)
                    throw console.log('讀取檔案失敗', error);
                console.log('讀取檔案成功', data);

                fs.readFile('./doc/text3.txt', (error, data) => {
                    if (error)
                        throw console.log('讀取檔案失敗', error);
                    console.log('讀取檔案成功', data);
                })
            })
        })
    })

Promise (解決回撥地獄的方法)

promise 使傳統的回撥巢狀轉化為回撥鏈式, 優雅的解決了回撥地獄造成的問題

p
    .then((data) => {
        console.log('接收 resolve 的正常執行序列');
        console.log('讀取檔案成功', data);
        return p1; 
    })
    .then((data) => {
        console.log('接收 resolve 的正常執行序列');
        console.log('讀取檔案成功', data);
        return p2;

    })
    .then((data) => {
        console.log('接收 resolve 的正常執行序列');
        console.log('讀取檔案成功', data);
        return p2;

    })
    .catch((error) => {
        console.log('接收 reject 的異常執行序列');
        console.log('讀取檔案失敗', error);
    })
    .finally(() => {
        console.log('最終執行')
    })

promise 應用

用 promise 封裝 readFile 和 writeFile

exports.pReadFile = function (fileUrl) {
    return new Promise(function (resolve, reject) {
        console.log('開始執行 promise 例項的回撥, 最先執行');

        // 非同步函式
        fs.readFile(fileUrl, (error, data) => {
            if (error) reject(error);
            else {
                resolve(data.toString());
            }
        })

    })
}


exports.pWriteFile = function (fileUrl, content) {
    return new Promise(function (resolve, reject) {
        console.log('開始執行 promise 例項的回撥, 最先執行');

        // 非同步函式
        fs.writeFile(fileUrl, content, (error) => {
            if (error) reject(error);
            else resolve(1);
        })

    })
}

呼叫

pReadFile('./doc/text1.txt')
    .then((data) => {
        console.log('讀取檔案成功!', data);
        return pReadFile('./doc/text.txt');
    })
    .then((data) => {
        console.log('讀取檔案成功!', data);
    })
    .catch((err) => {
        console.log(typeof (err));
        console.log('讀取失敗!', err);
    })
    .finally(() => {
        console.log('最終執行')
    })