簡體   English   中英

在JavaScript / Node.js中,如何使用Async / Await

[英]In JavaScript/Node.js, how to use Async/Await

在JavaScript / Node.js中,如何對下面的代碼使用Async / Await來返回帶有a,b,c和d的placeName。

test.csv有c,d

var placeName = ["a","b"];
var csvFile = 'test.csv';
fs.readFile(csvFile, 'UTF-8', function(err, csv) {
  $.csv.toArrays(csv, {}, function(err, data) {
    for(var i=0, len=data.length; i<len; i++) {
      console.log(data[i]); //Will print every csv line as a newline
      placeName.push(data[i][0].toString());
    }
  });
   console.log(placeName); //Inside the function the array show a,b,c,d
});

// Prints only a and b. Did not add c & d from the csv.
console.log(placeName); 

創建一個返回承諾的函數

await操作符等待諾言被兌現,並且只能在async函數中使用-調用時返回諾言。 因此,更新地名將需要編寫為返回諾言的函數。 可以對所有操作使用一個promise,但不建議這樣做:

function addNames(placeName, csvFile) {
    return new Promise( (resolve, reject) => {
        fs.readFile(csvFile, 'UTF-8', function(err, csv) {
            if(err) {
               reject(err);
            }
            else {
                $.csv.toArrays(csv, {}, function(err, data) {
                    if( err) {
                        reject( err);
                    }
                    else {
                        for(var i=0, len=data.length; i<len; i++) {
                            console.log(data[i]); //print supplied data elements
                            placeName.push(data[i][0].toString());
                        }
                    }
                    resolve( placeName);
                });

            }
        });
    });
}

盡管未經測試,但這是基於發布的代碼的:輸入的placeName數組已就地修改。 如果滿足,則將promise值設置為修改后的數組。 但是..

減少縮進代碼

注意,添加了更多節點樣式的回調操作后,代碼變得更加縮進? 極端地講,這可能導致一種稱為“回調地獄”的情況-難以編寫,無法正確編譯或維護。

刪除嵌套的回調是Promise的設計目標之一,可以通過分別使操作分散來實現。 下面的示例不僅分離讀取和解碼,還轉換解碼后的數據並將其添加到現有數組中:

function readCsvFile( csvFile) {
    return new Promise( (resolve, reject)  => {
        fs.readFile(csvFile, 'UTF-8',
           (err, csv) => err ? reject(err) : resolve( csv)
        );
    });
}
function decodeCsv( csv) {
    return new Promise( (resolve, reject) => {
        $.csv.toArrays(csv, {},
           (err, data) => err ? reject( err) : resolve( data)
        );
    });
}
function extractNames( data) {
   return data.map( item => item[0].toString());
}

function addNames( placeName, csvFile) {
    return readCsvFile( csvFile)
    .then(decodeCsv)
    .then(extractNames)
    .then(  // push new names to placeName and return placeName
       names => names.reduce( (a,name) => {a.push(name);return a}, placeName)
     );
}

作為承諾鏈的一部分進行呼叫

不使用異步/等待的用法需要在數據可用或發生錯誤后異步添加承諾處理程序以實現實現和拒絕。

var placeName = ["a","b"];
var csvFile = 'test.csv';

addNames( placeName, csvFile)
.then( placeName => console.log(placeName)) // log updated places
.catch( err => console.log( err));  // or log the error.

await用法

如前所述, await運算符只能在異步函數內部使用。 它等待已實現的承諾數據,以便可以在同一功能內對其進行進一步處理。

async function example() {

    var placeName = ["a","b"];
    var csvFile = 'test.csv';

    await addNames( placeName, csvFile);
    // do something with placeName

    return somethingElse;       
}

未顯示將實現和拒絕處理程序添加到調用example返回的promise中。

關於return await ...

請注意,從異步函數返回的承諾將解決通過調用該函數返回的承諾。 因此,

 return await operand

包含不必要的await運算符。

編寫異步函數而不是普通函數(TLDR)

在節點中使用async函數仍然需要將使用錯誤/成功回調的操作轉換為返回承諾的請求(“使操作承諾”),但是從語法上允許編寫處理請求的代碼,該請求將在await操作之后立即寫入。 生成的代碼在樣式上與過程代碼相似。 例如:

function readCsvFile( csvFile) {
    return new Promise( (resolve, reject)  => {
        fs.readFile(csvFile, 'UTF-8',
           (err, csv) => err ? reject(err) : resolve( csv)
        );
    });
}
function decodeCsv( csv) {
    return new Promise( (resolve, reject) => {
        $.csv.toArrays(csv, {},
           (err, data) => err ? reject( err) : resolve( data)
        );
    });
}

async function addNames( placeName, csvFile) {
    let csv = await readCsvFile( csvFile);
    let arrays = await decodeCsv( csv);
    let names = arrays.map( item => item[0].toString());
    placeName.push.apply( placeName, names);
    return placeName;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM