简体   繁体   中英

How to promisify Cordova File plugin?

I'd like to promisify a method within the Apache Cordova File plugin, but I'm having an issue with 'this'.

Initially, I was using arrow functions, but removed those when the issue with 'this' started occurring.

    /**
     * @param {Function} funcToPromisify -
     * @param {*} firstArgForFuncToPromisify -
     * @returns {Promise<any>} -
     */
    const promisifyFunctionOne = function(funcToPromisify, firstArgForFuncToPromisify) {
        return new Promise(function (resolve, reject) {
            funcToPromisify(firstArgForFuncToPromisify, resolve, reject);
        });
    };


    /**
     * @param {Function} funcToPromisify -
     * @returns {Promise<any>} -
     */
    const promisifyFunctionTwo = function(funcToPromisify) {
        return new Promise(function(resolve, reject) {
                funcToPromisify(resolve, reject);
            }
        );
    };


    /**
     * @param {string} pathToFile -
     * @param {Function} urlResolverFunc -
     * @param {object} stateObj -
     * @returns {void} -
     */ 
    const readFile = async function(pathToFile, urlResolverFunc) {
        const fileEntry = await promisifyFunctionOne(urlResolverFunc, pathToFile);  
        console.log(fileEntry); 
        try {
            const fileObj = await promisifyFunctionTwo(fileEntry.file);            
            let reader = new FileReader();        
            reader.onloadend = function() {
                console.log('Successful file read: ' + this.result);            
            };        
            reader.readAsText(fileObj);                    
        }
        catch(error) {        
            console.log(error);
        }
    };

    // Example of how readFile() is being called.
    readFile(pathToFile, window.resolveLocalFileSystemURL);


I'd like to be able to promisify the function FileEntry.file(), but I'm getting this error when attempting this: TypeError: this.toInternalURL is not a function at FileEntry.file (FileEntry.js:82)

That code can be viewed here: https://github.com/apache/cordova-plugin-file/blob/74a46467a081a87bb69b3f2518cbb1db5375028f/www/FileEntry.js#L80

It's okay for your to use arrow functions when defining promisify . Here's a basic exmample which doesn't depend on context ( this ) -

 const promisify = (f) => (...a) => new Promise ((res, rej) => f (...a, res, rej)) const basic = (a, b, c, success, failure) => c === 0 ? failure (Error("c cannot be zero")) : success (a + b + c) promisify(basic)(1, 2, 3).then(console.log, console.error) // 6 promisify(basic)(1, 2, 0).then(console.log, console.error) // Error: "c cannot be zero" 

Now for a function that needs context, watch how we use .bind to preserve context -

 const promisify = (f) => (...a) => new Promise ((res, rej) => f (...a, res, rej)) const account = { balance: 100 , withdraw: function (amount, success, failure) { if (amount > this.balance) failure(Error("insufficient funds")) else (this.balance -= amount, success(this)) } } const withdraw = promisify(account.withdraw.bind(account)) withdraw(35).then(console.log, console.error) // { balance: 65, withdraw: fn... } withdraw(9999).then(console.log, console.error) // Error: "insufficient funds" 


Note this differs from the node-style promisify where async functions only take one (1) callback and errors are always passed as the first argument to the callback -

 const promisify = f => (...a) => new Promise ((res, rej) => f (...a, (e, x) => e ? rej(e) : res(x) ) ) const divide = (a, b, nodeCallback) => b === 0 ? nodeCallback(Error("cannot divide by zero")) : nodeCallback(null, a/b) const pdivide = promisify(divide) pdivide(10,2).then(console.log, console.error) // 5 pdivide(10,0).then(console.log, console.error) // Error: "cannot divide by zero" 

NB, promisify as defined in this last snippet is included with Node as util.promisify

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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