简体   繁体   English

如何从图书馆创建承诺

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM