繁体   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