赞
踩
关于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");
用node执行上述代码以后,你会得到这样的结果顺序:
RunPos:1
RunPos:end2
RunPos:begin
RunPos:end
RunPos:success
data: ****此处忽略****
await是个好东西,它可以让你以同步的代码形式去写异步代码.比如:
const fsPromise = require('fs/promises');
async function test(file){
let ret = await fsPromise.readFile(file, "utf-8");
console.log("返回结果:",ret);
}
test("./package.json");
如果你追求极简…甚至可以这样写…
(async () => {console.log("返回结果:",await require('fs/promises').readFile("./package.json", "utf-8"))})();
可以看到,上述的代码量少了不少,而且也便于我们理解和做接下来的操作.
上述一波操作节省了我们许多寿命…简直无敌…
举个栗子:
const fsPromise = require('fs/promises');
let ret = async function (file) {
return await fsPromise.readFile(file, "utf-8");
}
console.log("ret:", ret);
上述代码执行输出的是这个这玩意:
ret: [AsyncFunction: ret]
可以看到,输出的并不是我们期待的数据.而是一个AsyncFunction对象.
由此可见,添加上async关键字的函数,会导致函数变为了一个新的AsyncFunction对象,你可以粗略的把它看成和Promise 一样…
其实,在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);
但是你可以通过then()方法去获取这个返回值,但它依旧是异步后的结果…
这不是BUG,而是它异步的运行机制决定的.
基于这个返回结果你要干的事儿还得放在异步里面,否则就相当于菜都从锅里倒出来了才想起来往锅里撒盐…
首先:我们在上面了解到了async实际上是将函数变成了一个新的异步操作对象.
其次:你要知道await规定必须放在async函数当中执行,放在其他地方会报错.
原因:await 会阻塞后面代码执行,它规定必须放在async异步操作当中使用.
否则你将永远无法执行完毕这个任务.试想一下await放在主程序中的样子…
//注意伪代码,不可用!
let a=0;
await ((a==2)=>{})();
a=2;
console.log("你永远休想得到我!!")
上述代码程序永远也没有执行到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);
抱歉,开个小玩笑…
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");
虽然还是异步操作,但是你可以同步的逻辑去写这些代码了!
如果你觉得本文讲的不够通透.可以参考这篇帖子:
理解 JavaScript 的 async/await
https://segmentfault.com/a/1190000007535316
PS:当你想学习并记住一个东西的时候,最好就去写教程,你会在书写的过程当中不停的翻阅资料和发现新问题,从而彻底领悟其中的精髓.比如你想要记歌词,你就去做LRC歌词,不要复制,从头到尾用耳朵把歌词扒下来.当你完成以后,你会发现你已经熟记于心.顺便还可以分享给他人使用.
感谢观看,别忘留个赞!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。