异步回调函数传值问题

如果调用的函数接受一个回调函数作为参数,那么怎么把回调函数获取的值传递出去呢?直接return是不可能做到的,本文探讨几种解决方案

/**
 * 创建一个项目
 * @class
 * @param {number} id
 * @param {string} name
 * @param {string} desc
 */
function Project(id, name, desc) {
  this.id = id;
  this.name = name;
  this.desc = desc;
}
/**
 * 获取项目图片
 * @param {number} id 项目编号
 * @callback 请求结果
 */
Project.prototype.getProjectImages = function (id, callback) {
  setTimeout(() => {
    var err = false;
    var res = `项目编号${id}的图片`;
    callback && callback(err, res);
  }, 2000);
};

var project = new Project(1, "test", "test project");

var outter = ''
project.getProjectImages(1, (err, res) => {
  if (err) {
    console.log("获取图片失败");
  } else {
    console.log(res);
    // 项目编号1的图片
    outter = res
  }
});
console.log(outter)
// ''

以上是初始代码,getProjectImages是一个异步函数,在打印outter时,这个异步函数还没有返回结果,因此打印的outter为空。下面来解决这个问题

使用回调函数

利用回调函数将结果传递出去

/**
 * 创建一个项目
 * @class
 * @param {number} id
 * @param {string} name
 * @param {string} desc
 */
function Project(id, name, desc) {
  this.id = id;
  this.name = name;
  this.desc = desc;
}
/**
 * 获取项目图片
 * @param {number} id 项目编号
 * @callback 请求结果
 */
Project.prototype.getProjectImages = function (id, callback) {
  setTimeout(() => {
    var err = false;
    var res = `项目编号${1}的图片`;
    callback && callback(err, res);
  }, 2000);
};
var project_list = [
  new Project(1, "java", "java项目"),
  new Project(2, "javascript", "javascript项目"),
];

function getImages(id, fn) {
  var index = project_list.findIndex((item) => item.id === id);
  var project = project_list[index];

  project.getProjectImages(id, (err, res) => {
    if (err) {
      console.log("获取图片失败");
    } else {
      fn(res);
    }
  });
}
getImages(1, (imgs) => {
  console.log(imgs);
  // 项目编号1的图片
});

我们重新构建一个函数getImages,它接受必要参数和一个回调函数fn,利用这个回调函数传递异步函数执行结果

使用Promise(推荐)
/**
 * 创建一个项目
 * @class
 * @param {number} id
 * @param {string} name
 * @param {string} desc
 */
function Project(id, name, desc) {
  this.id = id;
  this.name = name;
  this.desc = desc;
}
/**
 * 获取项目图片
 * @param {number} id 项目编号
 * @callback 请求结果
 */
Project.prototype.getProjectImages = function (id, callback) {
  setTimeout(() => {
    var err = false;
    var res = `项目编号${1}的图片`;
    callback && callback(err, res);
  }, 2000);
};
var project_list = [
  new Project(1, "java", "java项目"),
  new Project(2, "javascript", "javascript项目"),
];

function getImages(id) {
  return new Promise((resolve, reject) => {
    var index = project_list.findIndex((item) => item.id === id);
    var project = project_list[index];
    project.getProjectImages(id, (err, res) => {
      if (err) {
        return reject(err);
      } else {
        return resolve(res);
      }
    });
  });
}
getImages(1)
  .then((res) => {
    console.log(res);
    // 项目编号1的图片
  })
  .catch((err) => {
    console.log(err);
  });

上面使用Promise对异步回调的结果进行封装,这是解决许多现存库只支持异步回调不支持Promise的一般做法。resolve和reject不会直接返回,一般加上return

使用async/await改写
/**
 * 创建一个项目
 * @class
 * @param {number} id
 * @param {string} name
 * @param {string} desc
 */
function Project(id, name, desc) {
  this.id = id;
  this.name = name;
  this.desc = desc;
}
/**
 * 获取项目图片
 * @param {number} id 项目编号
 * @callback 请求结果
 */
Project.prototype.getProjectImages = function (id, callback) {
  setTimeout(() => {
    var err = false;
    var res = `项目编号${1}的图片`;
    callback && callback(err, res);
  }, 2000);
};
var project_list = [
  new Project(1, "java", "java项目"),
  new Project(2, "javascript", "javascript项目"),
];

function getImages(id) {
  return new Promise((resolve, reject) => {
    var index = project_list.findIndex((item) => item.id === id);
    var project = project_list[index];
    project.getProjectImages(id, (err, res) => {
      if (err) {
        return reject(err);
      } else {
        return resolve(res);
      }
    });
  });
}

async function main() {
  var res = await getImages(1);
  console.log(res);
}
main();

你可能感兴趣的:(异步回调函数传值问题)