我想使用promises,但我有一个回调API,格式如下:
window.onload; // set to callback
...
window.onload = function() {
};
Run Code Online (Sandbox Code Playgroud)
function request(onChangeHandler) {
...
}
request(function() {
// change happened
...
});
Run Code Online (Sandbox Code Playgroud)
function getStuff(dat, callback) {
...
}
getStuff("dataParam", function(err, data) {
...
})
Run Code Online (Sandbox Code Playgroud)
API;
API.one(function(err, data) {
API.two(function(err, data2) {
API.three(function(err, data3) {
...
});
});
});
Run Code Online (Sandbox Code Playgroud)
我已经将我的代码重组为承诺,并构建了一个由多个回调组成的精彩长扁平承诺链.then()
.最后我想返回一些复合值,并且需要访问多个中间承诺结果.但是,序列中间的分辨率值不在最后一个回调的范围内,我该如何访问它们?
function getExample() {
return promiseA(…).then(function(resultA) {
// Some processing
return promiseB(…);
}).then(function(resultB) {
// More processing
return // How do I gain access to resultA here?
});
}
Run Code Online (Sandbox Code Playgroud) 我编写的代码看起来像:
function getStuffDone(param) { | function getStuffDone(param) {
var d = Q.defer(); /* or $q.defer */ | return new Promise(function(resolve, reject) {
// or = new $.Deferred() etc. | // using a promise constructor
myPromiseFn(param+1) | myPromiseFn(param+1)
.then(function(val) { /* or .done */ | .then(function(val) {
d.resolve(val); | resolve(val);
}).catch(function(err) { /* .fail */ | }).catch(function(err) {
d.reject(err); | reject(err);
}); | });
return d.promise; /* or promise() */ | });
} | }
Run Code Online (Sandbox Code Playgroud)
有人告诉我这个被称为" 延迟反模式 "或" Promise
构造函数反模式 ",这个代码有什么不好,为什么这被称为 …
我已经开发了几年的JavaScript,我根本不理解有关承诺的大惊小怪.
似乎我所做的只是改变:
api(function(result){
api2(function(result2){
api3(function(result3){
// do work
});
});
});
Run Code Online (Sandbox Code Playgroud)
无论如何,我可以使用像async这样的库,例如:
api().then(function(result){
api2().then(function(result2){
api3().then(function(result3){
// do work
});
});
});
Run Code Online (Sandbox Code Playgroud)
哪个代码更多,可读性更低.我没有在这里获得任何东西,它也不会突然神奇地"平坦".更不用说必须将事物转换为承诺.
那么,这里的承诺有什么大惊小怪?
无论是ES6 Promise还是蓝鸟Promise,Q Promise等.
如何测试以查看给定对象是否为Promise?
在Node.js添加了对promises的原生支持之后,还有理由使用像Q或BlueBird这样的库吗?
例如,如果您正在开始一个新项目并让我们在这个项目中假设您没有任何使用这些库的依赖项,那么我们是否可以说实际上没有理由使用这些库?
我看了一下bluebird promise FAQ,其中提到了这.then(success, fail)
是一个反模式.我不太了解它对try和catch的解释.以下是什么问题?
some_promise_call()
.then(function(res) { logger.log(res) }, function(err) { logger.log(err) })
Run Code Online (Sandbox Code Playgroud)
似乎这个例子建议以下是正确的方法.
some_promise_call()
.then(function(res) { logger.log(res) })
.catch(function(err) { logger.log(err) })
Run Code Online (Sandbox Code Playgroud)
有什么不同?
在Bluebird的util.js
文件中,它具有以下功能:
function toFastProperties(obj) {
/*jshint -W027*/
function f() {}
f.prototype = obj;
ASSERT("%HasFastProperties", true, obj);
return f;
eval(obj);
}
Run Code Online (Sandbox Code Playgroud)
出于某种原因,在返回函数之后有一个声明,我不知道它为什么存在.
同样,它似乎是故意的,因为作者已经沉默了JSHint对此的警告:
'return'后无法访问'eval'.(W027)
这个功能到底是做什么的?难道util.toFastProperties
真的让一个对象的属性"快"?
我在Bluebird的GitHub存储库中搜索了源代码中的任何注释或者问题列表中的解释,但我找不到任何注释.
Bluebird提供了一种"终极"方法,可以在您的保证链中发生任何事情.我发现它非常方便用于清洁目的(比如解锁资源,隐藏装载机......)
在ES6原生承诺中是否有相同的东西?
以下是Finally方法的文档参考:
http://bluebirdjs.com/docs/api/finally.html
谢谢
我仍然是相当新的承诺,目前正在使用蓝鸟,但我有一个场景,我不太确定如何最好地处理它.
例如,我在快递应用程序中有一个承诺链,如下所示:
repository.Query(getAccountByIdQuery)
.catch(function(error){
res.status(404).send({ error: "No account found with this Id" });
})
.then(convertDocumentToModel)
.then(verifyOldPassword)
.catch(function(error) {
res.status(406).send({ OldPassword: error });
})
.then(changePassword)
.then(function(){
res.status(200).send();
})
.catch(function(error){
console.log(error);
res.status(500).send({ error: "Unable to change password" });
});
Run Code Online (Sandbox Code Playgroud)
所以我追求的行为是:
所以,目前抓到似乎没有停止的链接,这是有道理的,所以我想知道如果有,我以某种方式迫使链停在基于错误的某一点的方式,或是否有更好的办法构造它以获得某种形式的分支行为,就像有一种情况一样if X do Y else Z
.
任何帮助都会很棒.
bluebird ×10
javascript ×10
promise ×9
node.js ×5
q ×4
es6-promise ×3
callback ×2
performance ×1
scope ×1
v8 ×1