当前位置:   article > 正文

彻底搞懂JS异步Promise async await怎么用_const fspromise = require('fs/promises')

const fspromise = require('fs/promises')

Promise 能干啥,它怎么用:

关于Promise建议大家先去康康->这个视频<-,简洁易懂. 具体用法不过多叙述.

以往Promise示例代码

const fs = require('fs');
const p = new Promise((resolve, reject) => {
    console.log("RunPos:1");
    fs.readFile('./package.json', "utf-8", (err, data) => {
        if (err) {
            console.log("RunPos:err");
            reject(err);
        } else {
            console.log("RunPos:success");
            resolve(data);
        }
    })
    console.log("RunPos:end2");
});

console.log("RunPos:begin");
p.then(data => { console.log("data:",data) }).catch(err => { console.error("err:",err) });
console.log("RunPos:end");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

用node执行上述代码以后,你会得到这样的结果顺序:

RunPos:1
RunPos:end2
RunPos:begin
RunPos:end
RunPos:success
data: ****此处忽略****
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

当你用上了await以后的代码…

await是个好东西,它可以让你以同步的代码形式去写异步代码.比如:

const fsPromise = require('fs/promises');
async function test(file){
	let ret = await fsPromise.readFile(file, "utf-8");
	console.log("返回结果:",ret);
}
test("./package.json");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果你追求极简…甚至可以这样写…

(async () => {console.log("返回结果:",await require('fs/promises').readFile("./package.json", "utf-8"))})();
  • 1

可以看到,上述的代码量少了不少,而且也便于我们理解和做接下来的操作.
上述一波操作节省了我们许多寿命…简直无敌…


异步毕竟还是异步,我们无法通过return直接获取变量.

举个栗子:

const fsPromise = require('fs/promises');
let ret = async function (file) {
    return await fsPromise.readFile(file, "utf-8");
}
console.log("ret:", ret);
  • 1
  • 2
  • 3
  • 4
  • 5

上述代码执行输出的是这个这玩意:

ret: [AsyncFunction: ret]
  • 1

可以看到,输出的并不是我们期待的数据.而是一个AsyncFunction对象.

由此可见,添加上async关键字的函数,会导致函数变为了一个新的AsyncFunction对象,你可以粗略的把它看成和Promise 一样…

那么,return的东西到哪去了呢?

其实,在async里,函数return的值,会通过Promise.resolve()封装返回.
不管你有没有写return 它都会返回AsyncFunction对象.

也就是说…
这tm是个圈套…

你可以像套娃一样的无限套下去…但就是无法直接return一个值出去.

const fsPromise = require('fs/promises');
let ret = async function (file) {
    return await fsPromise.readFile(file, "utf-8");
}
ret("./package.json").then(data => { console.log("data:", data) });
console.log("ret:",ret);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

但是你可以通过then()方法去获取这个返回值,但它依旧是异步后的结果…
这不是BUG,而是它异步的运行机制决定的.
基于这个返回结果你要干的事儿还得放在异步里面,否则就相当于菜都从锅里倒出来了才想起来往锅里撒盐…

下面我们来具体分析一下它是怎么工作的:

首先:我们在上面了解到了async实际上是将函数变成了一个新的异步操作对象.
其次:你要知道await规定必须放在async函数当中执行,放在其他地方会报错.
原因:await 会阻塞后面代码执行,它规定必须放在async异步操作当中使用.
否则你将永远无法执行完毕这个任务.试想一下await放在主程序中的样子…

//注意伪代码,不可用!
let a=0;
await ((a==2)=>{})();
a=2;
console.log("你永远休想得到我!!")
  • 1
  • 2
  • 3
  • 4
  • 5

上述代码程序永远也没有执行到a=2那一天,但是在异步里面就不一样了

let she = "恋爱中";

function 等你失恋() {
    return new Promise((resolve, reject) => {
        let timer = setInterval(() => {
            if (she == "分手了") {
                resolve(); clearInterval(timer);
                //resolve()后的代码依旧可以执行.
            }
        }, 100);
    })
}

async function 见缝插针() {
    await 等你失恋();
    console.log("我终于有机会了!!");
}
见缝插针();

setTimeout(() => {
    console.log("分手了!!");
    she = "分手了";
}, 1000);


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

抱歉,开个小玩笑…

await等待的是一个结果,不停的在问Promise有没有结果…直到对方使用resolve()才算罢休.
触发await结束可以使用resolve()或reject(),return实际上也是触发resolve.

应用场景

虽然这个语法在本文看起来没什么用,甚至有些时候显得更臃肿.
但如果你在实际项目上使用它,将会有效的保留住头顶上的大把查克拉.
await的优势在于解决以往多层Promise嵌套,让你可以用正常的顺序逻辑编写代码而不是来回像套娃一样一直then下去…

const fsPromise = require('fs/promises');
async function test(file) {
    let ret = await fsPromise.readFile(file, "utf-8");
    let ret2 = await fsPromise.writeFile("./test.json", ret);
    console.log("返回结果:", ret, ret2);
}
test("./package.json");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

虽然还是异步操作,但是你可以同步的逻辑去写这些代码了!

结语

如果你觉得本文讲的不够通透.可以参考这篇帖子:

理解 JavaScript 的 async/await
https://segmentfault.com/a/1190000007535316

PS:当你想学习并记住一个东西的时候,最好就去写教程,你会在书写的过程当中不停的翻阅资料和发现新问题,从而彻底领悟其中的精髓.比如你想要记歌词,你就去做LRC歌词,不要复制,从头到尾用耳朵把歌词扒下来.当你完成以后,你会发现你已经熟记于心.顺便还可以分享给他人使用.

感谢观看,别忘留个赞!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/92698
推荐阅读
相关标签
  

闽ICP备14008679号