[英]How to create promises from library
I am confused on this one because every tutorial I have found so far assumes I can edit the library code, or that the library only has call backs or the call back as the last parameter. 我对此感到困惑,因为到目前为止我找到的每个教程都假定我可以编辑库代码,或者库只有回调或者回调作为最后一个参数。
The library I am using has every function set up like function(successCallBack(result), FailCallBack(error),options)
我正在使用的库的每个函数都设置为function(successCallBack(result), FailCallBack(error),options)
So in each instance, I end up using code like 所以在每个实例中,我最终都使用了像
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
};
How do I convert these into promises when I only have control of the call, and the success and failures? 当我只能控制呼叫,成功和失败时,如何将这些转换为承诺?
Also, as a bonus, the chains are accessing variables outside them. 此外,作为奖励,链条正在访问它们之外的变量。
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
}
Thanks 谢谢
You could use the following function. 您可以使用以下功能。 It accepts a function to promisify and options, and returns promise: 它接受promisify和options的函数,并返回promise:
let promisify = (fn, opts) => {
return new Promise((resolve, reject) => {
fn(resolve, reject, opts);
});
}
It could be used as follows: 它可以使用如下:
promisify(doStuff, options)
.then(data => console.log('Success call', data))
.catch(err => console.log('Error', err));
Rather than call promisify every time you want to use your function, you can wrap it once and get a new function that you can just use as needed. 不是每次想要使用函数时都调用promisify,而是可以包装一次并获得一个可以根据需要使用的新函数。 The new function will return a promise and resolve/reject instead of the success and fail callbacks. 新函数将返回一个promise并解决/拒绝而不是成功和失败的回调。 This particular version of promisify is specifically coded for the calling convention you show of fn(successCallback, errorCallback, options)
. promisify的这个特定版本是专门为您显示fn(successCallback, errorCallback, options)
的调用约定编写的fn(successCallback, errorCallback, options)
。 If you have other functions with different calling conventions, then you can create a different promisify version for them: 如果您有其他具有不同调用约定的函数,则可以为它们创建不同的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);
});
}
}
So, then you would use this like this: 那么,你会像这样使用它:
// 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
});
The advantage of doing it this way is that you can "promisify" a given function of set of functions just once in your project and then just use the new promisified versions. 这样做的好处是,您可以在项目中“一致”一组函数的特定功能,然后只使用新的promisified版本。
Suppose you imported an object that had a whole bunch of these types of interfaces on it. 假设您导入了一个对象,该对象上有大量这些类型的接口。 You could then make yourself a promisifyObj()
function that would make a promisified interface for all the functions on the object. 然后你可以自己创建一个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);
}
});
}
So, if you had an object named myModule
that had all these methods with this non-promise interface on it, you could promisify that module in one step: 因此,如果您有一个名为myModule
的对象,其上包含所有这些非承诺接口的方法,您可以在一个步骤中宣传该模块:
promisifyAll(myModule);
And, then you could use any method from that object by just adding the "Promise" suffix to the method name: 然后,您可以通过在方法名称中添加“Promise”后缀来使用该对象中的任何方法:
myModule.someMethodPromise(options).then(results => {
// process results here
}).catch(err => {
// handle error here
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.