如果調(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();