異步回調(diào)函數(shù)傳值問題

如果調(diào)用的函數(shù)接受一個回調(diào)函數(shù)作為參數(shù),那么怎么把回調(diào)函數(shù)獲取的值傳遞出去呢?直接return是不可能做到的,本文探討幾種解決方案

/**
 * 創(chuàng)建一個項目
 * @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是一個異步函數(shù),在打印outter時,這個異步函數(shù)還沒有返回結果,因此打印的outter為空。下面來解決這個問題

使用回調(diào)函數(shù)

利用回調(diào)函數(shù)將結果傳遞出去

/**
 * 創(chuàng)建一個項目
 * @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的圖片
});

我們重新構建一個函數(shù)getImages,它接受必要參數(shù)和一個回調(diào)函數(shù)fn,利用這個回調(diào)函數(shù)傳遞異步函數(shù)執(zhí)行結果

使用Promise(推薦)
/**
 * 創(chuàng)建一個項目
 * @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對異步回調(diào)的結果進行封裝,這是解決許多現(xiàn)存庫只支持異步回調(diào)不支持Promise的一般做法。resolve和reject不會直接返回,一般加上return

使用async/await改寫
/**
 * 創(chuàng)建一個項目
 * @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();
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容