我想使用Promissions,但我有一个回调API,其格式如下:
一,。DOM加载或其他一次性事件:
window.onload;//设置为回调
...
window.onload=函数(){
};
二,。普通回调:
函数请求(onChangeHandler){
…
}
请求(函数(){
//发生了变化
…
});
三,。节点样式回调(“节点回退”):
函数getStuff(dat,回调){
…
}
getStuff(“数据参数”,函数(错误,数据){
…
})
四,。具有节点样式回调的整个库:
API;
API.one(函数(错误、数据){
API.2(函数(错误,数据2){
API.3(函数(错误,数据3){
...
});
});
});
如何在promises中使用API,如何“承诺”它
承诺有状态,开始时是待定的,可以解决以下问题:
- 完成表示计算成功完成
- 被拒绝表示计算失败
承诺返回函数不应抛出,而应返回拒绝。从承诺返回函数中抛出将迫使您同时使用}catch{和a.catch。使用promisified API的人不希望承诺抛出。如果您不确定异步API在JS中如何工作,请先查看此答案
1.DOM加载或其他一次性事件:
因此,创建承诺通常意味着指定它们何时结算,也就是说当它们移动到完成或拒绝阶段时,表明数据可用(并且可以通过访问。然后)
使用支持promise构造函数(如本机ES6承诺)的现代承诺实现:
函数加载(){
返回新承诺(功能(解决、拒绝){
window.onload=解析;
});
}
然后,您将使用这样的结果承诺:
load()。然后(函数(){
//加载后做事情
});
对于支持deferred的库(在这里我们使用$q作为示例,但稍后我们也将使用jQuery):
函数加载(){
var d=$q.defer();
window.onload=function(){d.resolve();};
回报承诺;
}
或者使用类似jQuery的API,挂接发生一次的事件:
函数完成(){
var d=$.Deferred();
$(“#myObject”)。一次(“单击”,函数(){
d、 解决();
});
返回d.promise();
}
2.普通回调:
这些API非常常见,因为回调在JS中很常见。让我们看看有onSuccess和onFail的常见情况:
函数getUserData(userId,onLoad,onFail){…
使用支持promise构造函数(如本机ES6承诺)的现代承诺实现:
函数getUserDataAsync(userId){
返回新承诺(功能(解决、拒绝){
getUserData(用户ID、解析、拒绝);
});
}
对于支持deferred的库(让我们在这里使用jQuery作为示例,但我们也使用了上面的$q):
函数getUserDataAsync(userId){
var d=$.Deferred();
getUserData(userId,函数(res){d.resolve(res);},函数(err){d.reject(err);});
返回d.promise();
}
jQuery还提供了一个$.Deferred(fn)表单,它的优点是允许我们编写一个非常接近新承诺(fn)表单的表达式,如下所示:
函数getUserDataAsync(userId){
返回延迟的美元(函数(dfrd){
getUserData(userId,dfrd.resolve,dfrd.reject);
}).promise();
}
注意:这里我们利用了一个事实,即jQuery deferred的解析和拒绝方法是“可分离的”;也就是说,它们绑定到jQuery.deferred()的实例。并非所有lib都提供此功能
3.节点样式回调(“节点回退”):
节点样式回调(Nodeback)具有特定的格式,其中回调始终是最后一个参数,其第一个参数是错误。让我们首先手动提示一个:
getStuff(“dataParam”,函数(err,data){…
致:
函数getStuffAsync(param){
返回新承诺(功能(解决、拒绝){
getStuff(参数,函数(错误,数据){
如果(错误!==null)拒绝(错误);
else解析(数据);
});
});
}
对于延迟,您可以执行以下操作(在本例中使用Q,尽管Q现在支持您更喜欢的新语法):
函数getStuffAsync(param){
var d=Q.defer();
getStuff(参数,函数(错误,数据){
如果(err!==null)d.拒绝(err);
否则d.解析(数据);
});
回报承诺;
}
一般来说,您不应该过多地手动实现承诺,大多数在设计时考虑到节点以及Node 8+中的本机承诺的承诺库都有一个内置的方法来实现节点回退
var getStuffAsync=Promise.promisify(getStuff);//蓝鸟
var getStuffAsync=Q.denodeify(getStuff);//Q
var getStuffAsync=util.promisify(getStuff);//本机承诺,仅限节点
4.具有节点样式回调的整个库:
这里没有黄金法则,你可以一个接一个地承诺。但是,一些promise实现允许你批量这样做,例如在Bluebird中,将nodeback API转换为promise API非常简单:
promisifyAll(API);
或者在节点中使用本机承诺:
const{promisify}=require('util');
const promiseAPI=Object.entries(API.map)([key,v])=>;({key,fn:promisify(v)}))
.reduce((o,p)=>;Object.assign(o,{[p.key]:p.fn}),{});
注:
- 当然,当你在
处理程序中时,你不需要承诺任何事情。从返回承诺。然后处理程序将根据承诺的价值来解决或拒绝。从处理程序抛出也是一个好的实践,并且会拒绝承诺-这就是著名的承诺抛出安全 - 在实际的
onload情况下,应该使用addEventListener而不是onX