MST

星途 面试题库

面试题:JavaScript异步操作中的Promise与Node默认异步回调的结合应用

假设你有一个Node.js项目,其中部分旧代码使用了传统的异步回调方式,而新功能打算使用Promise。请描述如何在同一个项目中合理地将两者结合使用,以避免回调地狱,同时举例说明如何将一个基于回调的函数(如`fs.readFile`)转换为Promise形式,并在Promise链中调用它。
48.3万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
  1. 结合使用回调和Promise
    • 回调函数包装成Promise:对于旧的基于回调的函数,可以将其包装成返回Promise的函数。这样在新功能开发中,可以使用Promise的链式调用风格,同时也能复用旧的回调函数。
    • 在Promise链中处理回调:在Promise链的合适位置,调用包装后的Promise化的旧函数。如果在旧回调函数内部需要调用新的Promise - based函数,可以在回调中返回一个Promise并进行处理。
  2. fs.readFile转换为Promise形式
    • fs.readFile是Node.js中用于读取文件的异步回调函数。其原形式为fs.readFile(path, [options], callback)
    • 可以通过以下方式将其转换为Promise形式:
const fs = require('fs');
const util = require('util');

const readFilePromise = util.promisify(fs.readFile);

readFilePromise('test.txt', 'utf8')
  .then(data => {
        console.log(data);
    })
  .catch(err => {
        console.error(err);
    });
  • 在这个例子中,util.promisifyfs.readFile转换为返回Promise的函数readFilePromise。这样就可以使用.then.catch来处理成功和失败的情况,避免了回调地狱。
  1. 在Promise链中调用它
    • 假设我们有一系列操作,先读取一个文件,然后根据文件内容进行其他操作。
const fs = require('fs');
const util = require('util');

const readFilePromise = util.promisify(fs.readFile);

function processData(data) {
    // 模拟处理数据
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (data.includes('success')) {
                resolve('Processed successfully');
            } else {
                reject('Processing failed');
            }
        }, 1000);
    });
}

readFilePromise('test.txt', 'utf8')
  .then(data => processData(data))
  .then(result => {
        console.log(result);
    })
  .catch(err => {
        console.error(err);
    });
  • 在这个Promise链中,首先通过readFilePromise读取文件,然后将读取到的数据传递给processData函数进行处理。processData函数也是基于Promise的,整个过程保持了链式调用的风格,避免了回调地狱。