繁体   English   中英

Promises中的异步函数

[英]Async function inside Promises

这是我的情况:

fetchData(foo).then(result => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(result + bar);
        }, 0)
    });
}).then(result => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve( result + woo);
        }, 0)
    });
}).then(result => {
    setTimeout(() => {
        doSomething(result);
    }, 0)
});

其中每个setTimeout都是使用回调模式的不同异步操作。

将每个函数包装在promise中真的很痛苦,我觉得代码看起来应该更像这样:

fetchData(foo).then(result => {
    setTimeout(() => {
        return result + bar;
    }, 0)
}).then(result => {
    setTimeout(() => {
        return result + woo;
    }, 0)
}).then(result => {
    setTimeout(() => {
        doSomething(result);
    }, 0)
});

显然这不起作用。

我使用Promises吗? 我真的必须在promises中包装所有现有的异步函数吗?

编辑:

实际上我意识到我的例子并不完全代表我的情况,我没有说清楚我的例子中的setTimeout是为了重新发布异步操作。 这种情况更能代表我的情况:

fetchData(foo).then(result => {
    return new Promise((resolve, reject) => {
        asyncOperation(result, operationResult => {
            resolve(operationResult);
        }, 0)
    });
}).then(result => {
    return new Promise((resolve, reject) => {
        otherAsyncOperation(result, otherAsyncResult => {
            resolve( otherAsyncResult);
        }, 0)
    });
}).then(result => {
        doSomething(result);
});

我使用Promises吗? 我真的必须在promises中包装所有现有的异步函数吗?

是。 是。

我觉得代码看起来应该更像这样

不,它不应该。 它应该看起来像这样:

function promiseOperation(result) {
    return new Promise((resolve, reject) => {
        asyncOperation(result, resolve, 0)
    });
}
function otherPromiseOperation(result) {
    return new Promise((resolve, reject) => {
        otherAsyncOperation(result, resolve, 0)
    });
}

fetchData(foo).then(promiseOperation).then(otherPromiseOperation).then(doSomething);

将每个函数包装在promise中真的很痛苦

好吧,不要每次都重复写出来。 你可以将这个包装抽象成一个函数!

function promisify(fn) {
    return value => new Promise(resolve => {
        fn(value, resolve, 0)
    });
}
const promiseOperation = promisify(asyncOperation);
const otherPromiseOperation = promisify(otherAsyncOperation);
fetchData(foo).then(promiseOperation).then(otherPromiseOperation).then(doSomething);

请注意,大多数promise库都附带了这样的promisification函数,因此您的整个代码将减少到这三行。

你正在使用诺言。 关于第一段代码的一个小注释:你没有​​从最后一个then()回调中返回一个promise:

...
}).then(result => {
    setTimeout(() => {
        doSomething(result);
    }, 0)
});

如果您只需要执行异步操作而不返回fetchData调用fetchData的最后一次异步操作的值,那么这是正确的。 如果需要返回此值,则还需要转换为承诺此操作:

fetchData(foo).then(result => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(result + bar);
        }, 0)
    });
}).then(result => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(result + woo);
        }, 0)
    });
}).then(result => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(doSomething(result));
        }, 0)
    });  
});

在这里,我想doSomething是一个返回值的同步函数。

这样说,如果你想减少创建每次包装setTimeout的承诺的噪音,你可以创建一个实用函数setTimeoutWithPromise

function setTimeoutWithPromise(operation, millisec) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(operation());
        }, millisec)
    });
}

并清理你的代码:

fetchData(foo)
    .then(result => setTimeoutWithPromise(() => result + bar, 0))
    .then(result => setTimeoutWithPromise(() => result + woo, 0))
    .then(result => setTimeoutWithPromise(() => doSomething(result), 0));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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