最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

在JavaScriptNode.js中,如何使用AsyncAwait

运维笔记admin8浏览0评论

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

在JavaScript / Node.js中,如何使用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); 
回答如下:

创建一个返回promise的函数

await运算符等待履行的承诺,并且只能在async函数中使用 - 这些函数在调用时返回一个promise。因此,需要将更新地名编写为返回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值设置为已修改的数组。但是......

Reducing indented code

请注意,代码变得更加缩进,添加了更多节点样式的回调操作?极端情况下这会导致称为“回调地狱”的情况 - 难以编写,无错误编译或维护。

删除嵌套回调是承诺的设计目标之一,可以通过单独的promisifying操作来实现。以下示例不仅分离读取和解码,还将转换解码数据并将其添加到现有数组:

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)
     );
}

称为承诺链的一部分

不使用async / await的用法要求在数据可用或发生错误后,添加用于实现和拒绝的promise处理程序异步调用:

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运算符只能在异步函数中使用。它等待完成的promise数据,以便可以在同一个函数内进一步处理。

async function example() {

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

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

    return somethingElse;       
}

通过调用example为返回的承诺添加履行和拒绝处理程序尚未显示。

关于return await ......

请注意,从异步函数返回的promise将解析通过调用该函数返回的promise。因此编码模式

 return await operand

包含一个不必要的await运算符。

编写异步函数而不是普通函数(TLDR)

在节点中使用async函数仍然需要将使用错误/成功回调的操作转换为返回promise的请求(“promisifying”操作),但在语法上允许编写代码处理请求在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;
}
发布评论

评论列表(0)

  1. 暂无评论