nodejs tutorial notes (d) fs continued synchronous asynchronous

B grateful station tutorial "Nodejs introductory tutorial _Nodejs + Koa2 combat video Tutorial - 2020 Update"
Reference:

  1. Synchronous Asynchronous: https: //www.liaoxuefeng.com/wiki/1022910821149312/1023025763380448
  2. The callback function callback:
    https://blog.csdn.net/rockage/article/details/79513450
  3. promise:https://www.liaoxuefeng.com/wiki/1022910821149312/1023024413276544

First, synchronous, asynchronous

fs module also provides a method of asynchronous and synchronous. Review what is an asynchronous method . Because JavaScript is single-threaded model, when an IO operation, JavaScript code without having to wait, but after passing the callback function, continue to follow the JavaScript code . Such as provided by the getJSON jQuery () operation:

$.getJSON('http://example.com/ajax', function (data) {
    console.log('IO结果返回后执行...');
});
console.log('不等待IO结果直接执行后续代码...');

The synchronized IO operations will need to wait for the function to return .

// 根据网络耗时,函数将执行几十毫秒~几秒不等:
var data = getJSONSync('http://example.com/ajax');

The benefits of synchronous operation of the code is simple, disadvantage is that the program will wait for IO operations, during the waiting time, can not respond to any other events. The asynchronous read without waiting for IO operations, but the code more difficult.
Synchronization method does not receive the callback function, if the synchronization error occurred reading the file, you need to use try ... catch catch the error.

try {
    var data = fs.readFileSync('sample.txt', 'utf-8');
    console.log(data);
} catch (err) {
    // 出错了
}

When asynchronous read files, you can catch the error directly with the callback function.

fs.readFile('sample.png', function (err, data) {
    if (err) {
        console.log(err);
    } else {
        console.log(data);
        console.log(data.length + ' bytes');
    }
});

Because JavaScript code execution environment Node is a server-side code, so most of the need to repeatedly execute business logic code in the server runtime, you must use the asynchronous code , otherwise, the synchronization code at run time, the server stops responding because JavaScript only a thread of execution.
When the server is started to be written to the state file if you need to read the configuration file, or end, you can use the synchronization code, because the code is executed only once, does not affect the normal operation of asynchronous execution server at the start and end.

Second, the recursive problem solving 2

Problem Description: wwwroot folder and below images css js index.html, to find all directories under the wwwroot directory, and then placed in an array

var path = './wwwroot'
var dirArr = [];

fs.readdir(path, (err, data)=>{
    if(err) {
        console.log(err);
        return;
    }
    // 递归实现
    (function getDir(i){
        if(i == data.length) { // 执行完成
            console.log(dirArr)
            return
        }

        fs.stat(path+'/'+data[i], (error, stats)=>{
            if(stats.isDirectory()) {
                dirArr.push(data[i])
            }
            getDir(i+1)
        })
    })(0)
})

Third, the new features

  1. Let and used as the var defined variables and let, a block scope const
  2. Shorthand property
var name = 'zhangsan'
var app = {
    "name":name
}
console.log(app.name)
// 如果属性名称和变量名一样,则可如下简写
var name = 'zhangsan'
var app = {
    name
}
console.log(app.name)
  1. Shorthand method
var name = 'zhangsan'
var app = {
    name,
    run:function() {
        console.log(`${this.name}在跑步`)
    }
}
app.run()
// 简写后
var name = 'zhangsan'
var app = {
    name,
    run() {
        console.log(`${this.name}在跑步`)
    }
}
app.run()
  1. Arrow function
setTimeout(function(){
    console.log('执行')
}, 1000)
// 改写后
setTimeout(()=>{
    console.log('执行')
}, 1000)

Fourth, handle asynchronous

4.1 callback function callback

After most programming languages, a function parameter is always from the outside to pass parameters within the function body, but if the parameter in the JS keyword "callback" is exactly the opposite, it represents the body of the function in the completion of certain operations within an external function calls out.

// callback传异步数据
function getData(callback) {
    // ajax
    setTimeout(()=>{
        var name = 'zhangsan'
        callback(name);
    }, 1000);
}

// 外部获取异步方法里的数据
getData((aaa)=>{
    console.log(aaa)
})

getData parameters for the callback function, callback function is invoked in post assigned to (aaa) => {console.log (aaa)}, the function passed getData alternative callback function. Because in the name callback function in the getData, the output is a good assignment 'zhangsan'.

4.2 ES6 newly defined promise to solve the asynchronous transfer parameters
  1. Introduction promise

We look at a simple example of Promise: generating a random number between 0 and 2, if less than 1, waiting to return to success after a period of time, otherwise fail:

function test(resolve, reject) {
    var timeOut = Math.random() * 2;
    log('set timeout to: ' + timeOut + ' seconds.');
    setTimeout(function () {
        if (timeOut < 1) {
            log('call resolve()...');
            resolve('200 OK');
        }
        else {
            log('call reject()...');
            reject('timeout in ' + timeOut + ' seconds.');
        }
    }, timeOut * 1000);
}

The test () function takes two parameters, these two parameters are the function, if successfully implemented, we will call resolve ( '200 OK'), on failure, we will call reject ( 'timeout in' + timeOut + ' seconds. '). As can be seen, Test () function is only concerned with its own logic, do not care and how to resolve the specific reject the processing result.
With the execution of the function, we can use a Promise object to execute it, and success or failure of the results at some future time:

var p1 = new Promise(test);
var p2 = p1.then(function (result) {
    console.log('成功:' + result);
});
var p3 = p2.catch(function (reason) { // 失败时用catch
    console.log('失败:' + reason);
});

Variable p1 is a Promise object, which is responsible for implementing the test function. Since the test function internally asynchronous execution when the function test is successful, we tell Promise objects:

// 如果成功,执行这个函数:
p1.then(function (result) {
    console.log('成功:' + result);
});

When the test function fails, we tell Promise objects:

p2.catch(function (reason) {
    console.log('失败:' + reason);
});
  1. Serial asynchronous task execution

Promise can do more things, for example, there are a number of asynchronous tasks, need to do first tasks 1, 2 and if successful then do the task, any task failed and is no longer continue to perform error handling function.
To perform such serial asynchronous tasks without Promise need to write the code nested layer by layer. With Promise, we simply write:

job1.then(job2).then(job3).catch(handleError); // 可以统一用一个catch处理错误

Which, job1, job2 and job3 are Promise objects.

  1. Asynchronous parallel execution of tasks Promise.all ()

In addition to a number of serial asynchronous tasks performed outside, Promise asynchronous tasks can be executed in parallel.
Imagine a page chat system, we need to get users from two different URL are personal information and friends list, these two tasks can be executed in parallel, () implemented Promise.all as follows:

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
    console.log(results); // 获得一个Array: ['P1', 'P2']
});
  1. Asynchronous tasks fault-tolerant Promise.race ()

In some cases, multiple asynchronous tasks for fault tolerance. For example, while reading the user's personal information to the two URL, just we need to get the first results can be returned. In this case, () implemented Promise.race:

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
    console.log(result); // 'P1'
});

Since p1 faster execution, Promise of the then () The obtained results 'P1'. p2 continued to perform, but the results will be discarded.

4.3 Async、Await
  1. async is used to declare an asynchronous function, await wait for the completion of an asynchronous method execution
  2. Returns the string and get with async await (not recommended)
async function test(){ // 会自动将返回值包装为promise
    return "你好nodejs"
}

console.log(test())

Output: Promise { 'Hello nodejs'}
To obtain "Hello NodeJS" string, rather than Promise, you need to use await function. Note that await to be defined in the asynchronous method.

async function main() {
    var data = await test(); // 获取异步方法里数据
    console.log(data);
}
main();
  1. async return promise object and get with await
async function test() { // 会自动将返回值包装为promise
    return new Promise((resolve, reject) => {
        setTimeout(()=>{
            var name = 'zhangsan'
            resolve(name);
        }, 1000);
    })
}

async function main() {
    var data = await test(); // 获取异步方法里数据
    console.log(data);
}
main();
  1. Exercise
    wwwroot folder and below images css js index.html, to find all directories under the wwwroot directory, and then placed in an array
fs = require('fs')

const path = './wwwroot'
let dirArr = [];

// 1. 定义一个isDir方法判断资源是目录还是文件
async function isDir(path)
{
    return new Promise((resolve, reject) => {
        fs.stat(path, (error, stats)=>{
            if(error) {
                console.log(error)
                reject(error)
                return;
            }
            if(stats.isDirectory()) {
                resolve(true);
            } else {
                resolve(false);
            }
        })
    })
}

// 2. 获取wwwroot
function main() {

  // 哪个方法里需要await,就把哪个直接外部方法设置为async
  fs.readdir(path, async (err, data) => {
    if (err) {
      console.log(err)
      return
    }

    for (let i = 0; i < data.length; i++) {
      // await语句执行完之后才会执行下面的语句
      if (await isDir(path+'/'+data[i])) {
        dirArr.push(data[i])
      }
    }

    console.log(dirArr)
  })
}

main()

Published 220 original articles · won praise 28 · views 80000 +

Guess you like

Origin blog.csdn.net/Ema1997/article/details/104355643