Promise与async/await解决node.js异步问题

前言

image.png

上述代码中是通过request进行请求一个url,通过这个url得到模板引擎中的参数。

我们在之前提到过,node.js是属于全局异步的,所以上面的http请求直接被跳过,接下来直接运行了模板渲染HTML的命令。

导致模板渲染并不能正确的载入参数,而他又不能直接写在HTTP请求中。因此遇到了这个令人头皮发麻的问题。

Promise

上述函数使用了Promise函数,名称翻译过来是 “承诺”,

简单的说,如果代码需要按照一定的顺序进行执行的时候,可以通过Promise函数。promise会根据他内置的三种状态(进行中Pending/已完成Resolved/已失败Rejected)执行对应的操作。

function test() {
    const response = new Promise(resolve => {
        setTimeout(() => {
            resolve("test");
         }, 2000);
    });
    response.then(data=>{
        console.log(data)
    })
}
test();

操作成功的时候执行resolve(),失败执行reject()。简单的来说,

当我们操作http访问、数据库、i/o等操作的时候,应该使用promise函数确保操作完整完成,而不是直接去执行下一句命令。

当执行完毕后,使用resolve函数声明promise已完成,之后再通过 .then函数获得promise中返回的内容。

更好的办法:async 与 await

上面简单的介绍了promise,可是我们在一个项目开发之中,我们不可能每次需要同步操作都要使用then()一下,如果我们的项目需要很多的同步步骤,难不成一层then()套一层then()?

很明显,这种方式并不适合我们的习惯。

async/await是对Promise的优化 , 是进一步的一种优化,在写代码时, 只需要在代码前加上async代表这是一个异步函数,然后将await写在需要的方法前面即可 。

async const demo(){
let a =await i()
}

await代表着等待,等待 i() 成功执行后才会往下继续。 这种方式更适合我们平常的编码习惯。

最终的更改

由于response似乎并不能直接返回body(并没有深究),所以直接使用promise将body返回出来,然后对then()增加等待await进行获得。

const request = require('request')  
    let mtitle    
    const response = new Promise(resolve => {
        request(ctx.query.url, (error, response, body)=>{    
            if (!error && response.statusCode == 200) {
                resolve(body)
                }    
        })                     
    })
    await response.then(body=>{
        mtitle =  body         
    })   
       
    mtitle = await getCenterText('<title>','</title>',mtitle)