欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

node.js异步编程初探2(promise)

程序员文章站 2022-04-10 16:33:42
node.js异步编程初探2问题:如果异步API后面的代码执行,依赖当前异步API的执行结果,但实际上后续代码在执行的时候异步API还没有返回结果,这个问题怎么解决?解决方案一:缺点解决方案二:解决方案三(最优):问题:如果异步API后面的代码执行,依赖当前异步API的执行结果,但实际上后续代码在执行的时候异步API还没有返回结果,这个问题怎么解决?例如:如果需要一次读取多个文件。解决方案一:const fs = require('fs');fs.readFile('./1.txt', 'utf...

问题:如果异步API后面的代码执行,依赖当前异步API的执行结果,但实际上后续代码在执行的时候异步API还没有返回结果,这个问题怎么解决?

例如:node.js异步编程初探2(promise)
如果需要一次读取多个文件。

解决方案一:

const fs = require('fs');
fs.readFile('./1.txt', 'utf8', (err, result1) => {
  console.log(reult1);
  fs.readFile('./2.txt', 'utf8', (err, result2) => {
    console.log(reult2);
    fs.readFile('./3.txt', 'utf8', (err, result3) => {
      console.log(reult3);
    })
  })
})
//输出结果
1
2
3

缺点

回调的多层嵌套,虽然能过解决需求,但会形成回调地狱的现象,不利于后期的维护。

解决方案二:

这是一种异步编程语法上的改进,可以将异步API的执行和结果的处理进行分离。
promise是构造函数。
基础代码形式:
node.js异步编程初探2(promise)
将异步API的执行和结果的处理进行分离。

const fs = require('fs');
let promise = new Promise((resolve, reject) => {
    fs.readFile('./1.txt', 'utf8', (err, result) => {
        if (err != null) {
            reject(err);
        } else {
            resolve(result);
        }
    })
});
promise.then((result) => {
    console.log(result);
})
.catch((err) => {
    console.log(err);
})

Promise解决回调地狱的问题

//此代码有点问题,promises解决回调地狱的形式就是这样的
function p1() {
  return new Promise((resolve, reject) => {
    fs.readFile('./1.txt', 'utf8', (err, result) => {
      console.log(result);
    })
  });
}

function p2() {
  return new Promise((resolve, reject) => {
    fs.readFile('./2.txt', 'utf8', (err, result) => {
      console.log(result);
    })
  });
}

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

解决方案三(最优):

使用async关键字:
1.在普通函数前面加上async关键字,普通函数就变成了异步函数。
2.异步函数默认的返回值是promise对象,省去了需要new promise的步骤
3.在异步函数的内部使用return关键字进行结果返回,结果会被包裹在promise对象中,return关键字替代了resolve方法。
4.在异步函数的内部使用throw关键字对错误进行抛出。
5.调用异步函数再链式调用then方法获取异步函数执行结果。
6.调用异步函数再链式调用catch方法获取异步函数执行的错误信息。

例如:

async function fn() {
  throw 'err'
  return 123;
}
fn().then((data) => {
  console.log(data);
}).catch((err) => {
  console.log(err);
})

await关键字:
1.await只能出现在异步函数中
2.awiat后面只能跟promise对象,写其他类型的API是不可以的
3.await可以暂停异步函数向下执行 等待promise对象返回结果后再向下执行
由此:
异步代码------------->同步代码

const fs = require('fs');
const promisify = require('util').promisify; //promisify可对现有的异步API进行包装,让其返回promise对象
const readFile = promisify(fs.readFile); //readFile就是一个新的可以返回promise对象的方法 
async function run() {
  let r1 = await readFile('./1.txt', 'utf8');
  let r2 = await readFile('./2.txt', 'utf8');
  let r3 = await readFile('./3.txt', 'utf8');
  console.log(r1);
  console.log(r2);
  console.log(r3);
}
run();

本文地址:https://blog.csdn.net/ryyzxf/article/details/109272882