Javascript 如何从库中创建承诺
我对此感到困惑,因为到目前为止,我找到的每个教程都假设我可以编辑库代码,或者库只有回调或回调作为最后一个参数 我使用的库的每个功能都设置为Javascript 如何从库中创建承诺,javascript,promise,Javascript,Promise,我对此感到困惑,因为到目前为止,我找到的每个教程都假设我可以编辑库代码,或者库只有回调或回调作为最后一个参数 我使用的库的每个功能都设置为 函数(成功回调(结果)、失败回调(错误)、选项) 因此,在每个实例中,我最终都会使用如下代码 var options={stuff1:1, stuff2:2}; doStuff(success,failure,options); function success(result){ //handle, usually with another ca
函数(成功回调(结果)、失败回调(错误)、选项)
因此,在每个实例中,我最终都会使用如下代码
var options={stuff1:1, stuff2:2};
doStuff(success,failure,options);
function success(result){
//handle, usually with another call to a similar function, chaining callbacks together
};
function failure(error){
//handle error
};
当我只能控制通话和成功与失败时,我如何将这些转化为承诺
此外,作为奖励,链正在访问它们之外的变量
var options={stuff1:1, stuff2:2};
doStuff(success,failure,options);
function success(result){
var options2={stuff1:1, stuff2:2};
doStuff2(function(result2){
processStuff(result1, result2);
},function(error){
//handle error
},options2)
};
function failure(error){
//handle error
};
function processSuff(result1,result2){
//do things to results
}
谢谢您可以使用以下功能。它接受promisify和options的函数,并返回promise:
let promisify = (fn, opts) => {
return new Promise((resolve, reject) => {
fn(resolve, reject, opts);
});
}
可按如下方式使用:
promisify(doStuff, options)
.then(data => console.log('Success call', data))
.catch(err => console.log('Error', err));
与每次需要使用函数时都调用promisify不同,您可以将它包装一次,然后得到一个新函数,您可以根据需要使用它。新函数将返回承诺和解决/拒绝,而不是成功和失败回调。promisify的这个特定版本是专门为您显示的
fn(successCallback,errorCallback,options)
的调用约定编写的。如果您有其他具有不同调用约定的函数,则可以为它们创建不同的promisify版本:
// return a promisified function replacement for this specific
// calling convention: fn(successCallback, errorCallback, options)
function promisify1(fn) {
return function(options) {
return new Promise((resolve, reject) => {
fn(resolve, reject, options);
});
}
}
那么,你可以这样使用它:
// do this once, somewhere near where doStuff is imported
let doStuffPromise = promisify1(doStuff);
// then, anytime you would normally use doStuff(), you can just use
// doStuffPromise() instead
doStuffPromise(options).then(results => {
// process results here
}).catch(err => {
// handle error here
});
这样做的好处是,您可以在项目中“promisify”一次给定的函数集,然后只使用新的promisify版本
假设您导入了一个对象,该对象上有一大堆这些类型的接口。然后,您可以创建一个
promisifyObj()
函数,为对象上的所有函数创建一个promisified接口
// a "Promise" version of every method on this object
function promisifyAll(obj) {
let props = Object.keys(obj);
props.forEach(propName => {
// only do this for properties that are functions
let fn = obj[propName];
if (typeof fn === "function") {
obj[propName + "Promise"] = promisify1(fn);
}
});
}
因此,如果您有一个名为myModule
的对象,该对象上有所有这些方法以及此非承诺接口,那么您可以在一个步骤中提示该模块:
promisifyAll(myModule);
然后,您可以使用该对象中的任何方法,只需在方法名称中添加“Promise”后缀:
myModule.someMethodPromise(options).then(results => {
// process results here
}).catch(err => {
// handle error here
});
“promisify”函数的工作版本,可用于创建新函数,该函数“包装”将传统回调接口转换为返回承诺的函数的现有函数:。此外,还有
.promisify()
和.promisifyAll()
。这两个函数都假定您有一个具有典型异步调用约定的函数,即最后一个参数为单回调。如果没有,您将不得不调整这些以适应您的调用约定。我有bluebird,但我还不知道如何正确使用它。由于您的函数包含两个回调,并且第一个和第二个参数对于异步调用来说是非标准的,所以您不能直接使用bluebird来实现。您必须为希望与承诺一起使用的每个函数创建自己的承诺返回包装器。@jfriend00啊,谢谢,这更好地解释了我的困惑。在`.then(()=>/*Success call*/)`中,它是如何得到结果的?我是否将success(result)函数调用放在那里?更新了代码,然后
回调将接受将传递给原始success
函数的参数。谢谢。我需要一点时间来测试实现它,但是如果让像我这样的javascript新手感到困惑的话,这看起来真的很好。我可以用这个来修复变量范围块,其中链中的最后一项读取每个链的结果吗?我不太明白你的意思。你能提供更多的细节吗?