vlambda博客
学习文章列表

异步编程解决方案是如何一步步优化的


有关【同步异】以及异步解决方案往期文章请参考下面链接,如果你都熟悉请跳过。




同步和异步的最大区别是异步API没有返回值。



function fn ( setTimeout(function () {           return 'abc'      }, 1000); } const msg = fn ();  console.log(msg) // undefined


我们打印msg是得不到返回值时,因为fn方法是同步任务,fn是异步任务,当getTimeout执行完,fn函数才执行,所以得不到返回值abc。


那么如何得到返回值呢?




答案就是回调函数




回调函数基本形式,给函数的实参传递一个方法,在形参中用callback传递

function fn (callback{}fn (() => {});





使用回调函数获取异步API执行结果
给fn传递一个方法,用callback接收,在方法里传递参数msg,在setTimeout方法里用callback传递实参。这样就实现里获取异步API的结果


function fn (callback) { setTimeout(function () { callback ('abc') }, 2000);}fn (function (msg) {  console.log(msg); // abc});


比如现在有一个需求,在nodejs中依次读取A、B、C文件。


1




思路1:因为fs.readFile方法也是个异步API。我们可以用回调函数依此读取文件内容,但是这样的问题是如果需要读取的文件很多,会造成回调地狱。



const fs = require('fs');fs.readFile('./1.txt', 'utf8', (err, res1) => { console.log(res1) fs.readFile('./2.txt', 'utf8', (err, res2) => { console.log(res2) fs.readFile('./3.txt', 'utf8', (err, res3) => { console.log(res3) }) })});


2




思路2:Promise出现的目的是解决Node.js异步编程中回调地狱的问题。

我们可以用promise的方式改写依此读取文件内容的方式。



function p1 () { return new Promise ((resolve, reject) => { fs.readFile('./1.txt', 'utf8', (err, res) => { resolve(res) }) });}
function p2 () { return new Promise ((resolve, reject) => { fs.readFile('./2.txt', 'utf8', (err, res) => { resolve(res) }) });}
function p3 () { return new Promise ((resolve, reject) => { fs.readFile('./3.txt', 'utf8', (err, res) => { resolve(res) }) });}p1().then((r1)=> { console.log(r1); return p2();}).then((r2)=> { console.log(r2); return p3();}).then((r3) => { console.log(r3)})


这样的方式虽然解决里回调地狱,但是每个方法都new里一个promise对象。


3




思路3:异步函数是异步编程语法的终极解决方案,它可以让我们将异步代码写成同步的形式,让代码不再有回调函数嵌套,使代码变得清晰明了。



const fn = async () => {};async function fn () {}




await关键字只能出现在异步函数中

await关键字可是暂停异步函数向下执行 直到promise返回结果



async function p1 () {  return fs.readFile('./1.txt''utf8', (err, res) => { console.log(res) })
}async function p2 () {  return fs.readFile('./2.txt''utf8', (err, res) => { console.log(res) })}async function p3 () { return fs.readFile('./3.txt', 'utf8', (err, res) => { console.log(res) })}
let res1 = await p1()let res2 = await p2()let res3 = await p3()


这样对比这用回调函数解决异步,异步函数就清晰简洁了很多。

Readings

在遇到困难时,内心总是渴望解决问题、带来和平的。这种心灵的呼唤——往往是不自觉的欲望——就是我所谓的“爱意”。


爱意的产生,是由于灵魂在驱策我们去学习如何真心地爱自己和对方。


如果我们能明白,爱意则能让我们克制冲动,用负责任的态度来处理我们心中的不快,不致说出责怪或指责的话,而用理解、体谅的话来取代。这样我们便成长了。



END



往期文章链接地址:

https://github.com/fqs1024/blog/blob/master/README.md



点个赞哦~