2017-09-08 47 views
0

我正在調試Node.js 8.4.0上的async/await代碼。形式#1按預期工作,打印「OK」,但版本#2崩潰隨機(至少每10次左右)有錯誤,比如將異步/等待回調傳遞給sass(C++)隨機崩潰

libc++abi.dylib: Pure virtual function called! 
Abort trap: 6 

Segmentation fault: 11 

這裏是我的代碼:

var sass = require('node-sass') 
var fs = require('fs') 

var scss = '@import "foo";' 

// Helper function that reads a given file, returning a promise 
function readFilePromise(filename) { 
    return new Promise((resolve, reject) => { 
    fs.readFile(filename, (err, buf) => { 
     if(err) { 
     console.log("ERROR", err) 
     reject(err) 
     } else { 
     resolve(buf) 
     } 
    }) 
    }) 
} 

// #1 Pass a normal callback that uses a promise - works as expected. 
sass.render({ 
    data: scss, 
    importer: (url, prev, done) => { 
    readFilePromise(__filename).then((contents) => { 
     done({ contents: '' }) 
    }) 
    }, 
}, function(err, result) { 
    console.log(err ? err : "OK") 
}) 

// #2 Pass async function - crashes. 
sass.render({ 
    data: scss, 
    importer: async (url, prev, done) => { 
    var contents = await readFilePromise(__filename) 
    done({ contents: '' }) 
    }, 
}, function(err, result) { 
    console.log(err ? err : "OK") 
}) 

我的問題:這是一個Node.js錯誤?薩斯錯誤?或者我做錯了什麼?

環境:macOS上的Node.js 8.4 Sierra,node-sass 4.5.3。

+0

我不能直接與C++進行交互操作,而且您也沒有任何C++代碼。我認爲C++標籤不合適,應該刪除。 – tambre

+1

在你的第二個例子中,你要回應對進口商的承諾,這將使SASS認爲它不是異步回調。如果你想在這裏使用async/await,我會放置一個匿名異步函數。然後你會像以前一樣返回undefined。 – Keith

+1

另一種選擇是聯繫'Node-sass'並詢問開發者他們是否可以檢查一個可容納的,然後將它作爲異步/等待兼容,並且你可以執行諸如 - >'importer:async(url,prev ){return {contents:await readFilePromise(__ filename); 'IOW:不需要完成回調。 – Keith

回答

2

您確定node-sass預計importer方法返回承諾嗎?因爲這就是async功能所做的。基於node-sass docs它似乎只能用於回調或同步實現importer的庫。您的實現立即返回承諾,並且lib認爲它是從同步版本返回的,並嘗試繼續使用承諾本身(而不是解析值)繼續工作。

+0

謝謝,這很可能是原因。早些時候,我有一個更復雜的設置,承諾返回*似乎*實際工作,可能是由於我自己的錯誤。 – tuomassalo