我有一个简化的函数,看起来像这样:
function(query) {
myApi.exec('SomeCommand', function(response) {
return response;
});
}
我想让它调用myApi。Exec,返回回调lambda中给出的响应。然而,上面的代码不能工作,只是立即返回。
只是为了一个非常hack的尝试,我尝试了下面的工作,但至少你知道我想要实现什么:
function(query) {
var r;
myApi.exec('SomeCommand', function(response) {
r = response;
});
while (!r) {}
return r;
}
基本上,“node.js/事件驱动”的好方法是什么?我希望我的函数等待,直到回调被调用,然后返回传递给它的值。
实现这一点的一种方法是将API调用封装到promise中,然后使用await来等待结果。
// Let's say this is the API function with two callbacks,
// one for success and the other for error.
function apiFunction(query, successCallback, errorCallback) {
if (query == "bad query") {
errorCallback("problem with the query");
}
successCallback("Your query was <" + query + ">");
}
// Next function wraps the above API call into a Promise
// and handles the callbacks with resolve and reject.
function apiFunctionWrapper(query) {
return new Promise((resolve, reject) => {
apiFunction(query,(successResponse) => {
resolve(successResponse);
}, (errorResponse) => {
reject(errorResponse);
});
});
}
// Now you can use await to get the result from the wrapped api function
// and you can use standard try-catch to handle the errors.
async function businessLogic() {
try {
const result = await apiFunctionWrapper("query all users");
console.log(result);
// the next line will fail
const result2 = await apiFunctionWrapper("bad query");
} catch(error) {
console.error("ERROR:" + error);
}
}
// Call the main function.
businessLogic();
输出:
Your query was <query all users>
ERROR:problem with the query
实现这一点的一种方法是将API调用封装到promise中,然后使用await来等待结果。
// Let's say this is the API function with two callbacks,
// one for success and the other for error.
function apiFunction(query, successCallback, errorCallback) {
if (query == "bad query") {
errorCallback("problem with the query");
}
successCallback("Your query was <" + query + ">");
}
// Next function wraps the above API call into a Promise
// and handles the callbacks with resolve and reject.
function apiFunctionWrapper(query) {
return new Promise((resolve, reject) => {
apiFunction(query,(successResponse) => {
resolve(successResponse);
}, (errorResponse) => {
reject(errorResponse);
});
});
}
// Now you can use await to get the result from the wrapped api function
// and you can use standard try-catch to handle the errors.
async function businessLogic() {
try {
const result = await apiFunctionWrapper("query all users");
console.log(result);
// the next line will fail
const result2 = await apiFunctionWrapper("bad query");
} catch(error) {
console.error("ERROR:" + error);
}
}
// Call the main function.
businessLogic();
输出:
Your query was <query all users>
ERROR:problem with the query
“好的node.js /事件驱动”的方法是不要等待。
与node等事件驱动系统一样,函数应该接受一个回调参数,该参数将在计算完成时被调用。调用者不应该等待正常意义上的值被“返回”,而是发送将处理结果值的例程:
function(query, callback) {
myApi.exec('SomeCommand', function(response) {
// other stuff here...
// bla bla..
callback(response); // this will "return" your value to the original caller
});
}
所以你不能这样使用它:
var returnValue = myFunction(query);
但就像这样:
myFunction(query, function(returnValue) {
// use the return value here instead of like a regular (non-evented) return value
});