嘗試靜態文章生產器 Part 2

前情提要

我想了很久,最後決定自己寫。不過老實說,比我想像中的複雜啊。其中最麻煩的,大概就是有關非同步的操作了。因為非同步操作呢,並不是馬上就會完成,所以回傳時也不全是完整的檔案。

寫幾個碰上的新問題吧。

非同步陣列

非同步操作是 AJAX 與檔案存取的核心機制。詳細不多說,因為之前就寫過了

事情是這樣的:我有一些需要存取的檔案。既然是一些檔案,那就需要一個陣列儲存。問題是……陣列裡面要怎麼做?

我後來查了一下,可以用 Promise 完成,然後用 Promise.all 把檔案全部都等出來。最後等要用到的時候,再去使用這個陣列的函式,當成 Promise 一類的非同步方法調用。

比方說:

const main = ( files_array = [] ) =>
{
    const func = ( fpath = "" ) => new Promise(( resolve, reject ) =>
        fs.readFile( fpath, "utf8", ( error, md_file ) =>
        {
            if( error ) reject( new Error( error ));
            resolve( md_file );
        })
    );
    return Promise.all(
        files_array.map( file => func( file ) )
    ).then( x => x );
}

const call = async( ary = [] ) =>
{
    return await main( ary );
};

call( ary );

async function 是一個解決非同步操作的新方案。在 async 裡面加入 await 關鍵字,函式就會等待 await 關鍵字的,直到行動結束為止。

This test

在寫測試時,有這樣的問題:

// Throw "this.timeout is undefined".
describe( "StaticSiteGenerator in AJAX mode", () =>
{
    this.timeout( 300000 );
});

查一下,原來 mocha 並沒有給 this 綁定,所以箭頭函式的 this 會跑掉。mocha 官方也不推薦箭頭函式。因此我在根函式把箭頭函式改回來:

describe( "StaticSiteGenerator in AJAX mode", function()
{
    this.timeout( 300000 );
});

參考資料