与我一起担任Java程序员,在新项目中学习现代JavaScript。我得到了Promises的概念来处理异步操作,但有没有理由“promisify”代码,强度方面几乎没有任何东西,并且不包含你需要等待的任何东西(如db查询,http请求等)?我遇到了这个后端node.js代码,它在promise中做了一些微不足道的事情:
const customersWithHeader; //assume this contains an array of rows loaded from CSV file
const allowedHeaderNames; //assume a string array with allowed header names (6 values)
return new Promise((resolve, reject) =>
allowedHeaderNames.find((name, index) => name !== customersWithHeader[0][index])
? reject({error: 'missing-header'})
: resolve(customersWithHeader.slice(1))
).then(/* Then follows code that does db queries on every row from the customer array, those are promisified by Promise.all() */)
没有什么可以等待的,只需检查一个小阵列与另一个小阵列。编写这样的代码有什么好处,而不仅仅是if和同步返回切片数组或抛出错误?对我而言,似乎不必要地实例化Promise。
答案 0 :(得分:3)
一种可能性是,编写该代码的人希望将来可以轻松扩展。想象一下,你想快速模拟一些东西,并且你知道它将来会异步 - 这意味着客户端代码(代码消耗你的异步代码)也必须是异步的。如果虚拟代码不是异步的,那么一旦改变就会破坏客户端代码。
将其视为契约/接口类型。
答案 1 :(得分:1)
是的,实际上有时会有。一个常见的情况是函数应该返回一个promise。
假设我正在使用一个库,其中一个类作为构造函数参数,是一个您实现的函数,它基本上存储数据供以后使用。该库并不关心您如何存储它,但它期望在存储成功时解析的promise。您可以使用异步流程(如fs.writeFile
)自然地存储它,或者如果您想使用同步存储解决方案(例如,您可能在浏览器中并且可以使用localStorage),您仍然可以返回一个承诺,但只是做同步的事情。
有很多次我遇到过需要回复承诺的情况,但没有任何异步的事情发生。
答案 2 :(得分:1)
以下是您显示的代码的替代方法:
function handleError(err) {
// do something with error
}
if (allowedHeaderNames.find((name, index) => name !== customersWithHeader[0][index])) {
return handleError({error: 'missing-header'});
} else {
// or some truly async thing
return new Promise((resolve, reject) => asyncFunction()).catch(handleError);
}
显然,只需强制链中的点以相同的异步方式处理就更清晰了。
答案 3 :(得分:1)
如果您使用抽象(接口)并期望实现函数返回一个promise,那么即使对于同步代码也可以返回Promise - 如果您直接使用生成的promise。例如:
let handler = {
handle: function(){ return Promise.resolve("something sync"); }
}
handler.handle(ctx).then((result)=>{...
然而,es7 async / await使得这一点毫无意义,因为你可以等待一个返回一个promise或一个值的函数;即该功能可以是异步或同步。
async function main(){
let handler = {
handle: function(){ return "something"; }
}
let result = await handler.handle(ctx);
}