rwson

rwson

一个前端开发

async/await学习

在处理javascript中异步的时候,回调往往是最让人恶心的,之前介绍过用Promise来处理异步的问题,但是即使用上了Promise,在处理回调上还是会有各种嵌套,今天来介绍下ES7中的async/await,由于在Nodejs中还未得到支持,所以需要借助一些npm包来实践,在这里用的是asyncawait

先来个原生文件读取的例子:

    const fs = require("fs");
    fs.readFile("test.txt", (ex, res) => {
       console.log(res.toString()); 
       
       //   do something...
       
       fs.readFile("test2.txt", (ex, res) => {
            console.log(res.toString());
            
            //  do something
       });
    });
    
    //  控制台输出
    xxxxx
    yyyyy

下面我们再用async/await实现一遍:

    const async = require("asyncawait").async;
    const await = require("asyncawait").await;
    let readFile = function(path) {
        return new Promise((resolve, reject) => {
            fs.readFile(path, (ex, res) => {
                if (ex) {
                    reject(ex);
                }
                resolve(res);
            });
        });
    }
    
    let asyncReadFile = async(() => {
        
        let fs = await (readFile("test.txt"));
        let fs2 = await (readFile("test2.txt"));
        
        console.log(fs.toString());
        console.log(fs2.toString());
    });
    
    asyncReadFile();

虽然代码可能比上面的多了一点,但是已经完全看不到回调嵌套的影子了,也能完成同样的功能,何乐而不为。😉

下面我们再来模拟一个异步请求的例子:

const async = require("asyncawait").async;
    const await = require("asyncawait").await;
    const http = require("http");
    
    http.createServer((req, res) => {

        switch (req.url) {
    
            case "/async-await":
                setTimeout(() => {
                    res.writeHead(200, { "Content-Type": "text/plain" });
                    res.end("request end");
                }, 5000);
                break;
    
            case "/async-await2":
            	setTimeout(() => {
            		res.writeHead(200, { "Content-Type": "text/plain" });
                    res.end("request end2");
            	}, 8000);
            	break;
    
        	default:
        		break;
    
        }
    }).listen(3000, "127.0.0.1");

    let requestUrl = function(path) {
        return new Promise((resolve, reject) => {
            http.get({
                hostname: 'localhost',
                port: 3000,
                path: path,
                agent: false
            }, (res) => {
                res.on("data", (data) => {
                    resolve(data);
                });
                res.on("error", (ex) => {
                    reject(ex);
                })
            });
        });
    }
    
    let asyncRequest = async(() => {
        let resp, resp2;
        await (requestUrl("/async-await").then((res) => {
        	console.log(res.toString());
            resp = res.toString();
        }).catch((ex) => {
            resp = "发生错误!";
        }));
    
        await (requestUrl("/async-await2").then((res) => {
            resp2 = res.toString();
        }).catch((ex) => {
            resp = "发生错误!";
        }));
        console.log(resp);
        console.log(resp2);
    });
    
    asyncRequest();
    
    //  控制台输出
    request end
    request end2

由此我们可以将async/await用在很多地方,比如例子中的文件读取、异步请求、nodejs中的查询数据库等等。