JS Promise:控制流

JS Promise: control flow

我必须通过 API 设置一些东西。重要的是,不同的功能是在彼此之后执行的。所有列出的功能 return 一个适当的承诺。

a(analyticsConfig._listConfig)
    .then(function() {
        return b(listName, analyticsConfig._fieldConfig);
    })
    .then(function() {
        return c(listName)
    })
    .then(function() {
        return d(analyticsConfig._roleConfig);
    })

我想使用 a.then(b(listName, analyticsConfig._fieldConfig)) 左右的东西,但你可能知道这行不通。

还有其他方法吗?

只有 b returns 一个 returns 承诺的函数才有效。您总是 必须 函数 作为回调传递给 then,这是没有办法的。然而,有很多方法可以构建一个。

抛开部分应用程序(使用 bind 或其他)、柯里化和诸如此类的东西,更好语法的最佳选择是 ES8 async/await

(async function() {
    await a(analyticsConfig._listConfig);
    await b(listName, analyticsConfig._fieldConfig);
    await c(listName);
    await d(analyticsConfig._roleConfig);
})();

或 ES6 箭头函数:

a(analyticsConfig._listConfig)
.then(() => b(listName, analyticsConfig._fieldConfig))
.then(() => c(listName))
.then(() => d(analyticsConfig._roleConfig))

你可以写成

a.then(b.bind(null, listName, analyticsConfig._fieldConfig))

或者,如果您使用 babel 转译您的代码,或者您的目标版本是 node > v4.,您可以

a.then(() => b(listName, analyticsConfig._fieldConfig))

可以绑定:

a.then(b.bind(context,listName,analyticsConfig._fieldConfig))

尽管如此,请务必将预期的上下文绑定到它。

根据the docs

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

您可以使用 async/await 执行以下操作:

function a() {
    console.log('Getting A...');
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Hello A!');
        }, 1000);
    });
}

function b() {
    console.log('Getting B...');
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Hello B!');
        }, 1000);
    });
}

function c() {
    console.log('Getting C...');
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Hello C!');
        }, 1000);
    });
}

function d() {
    console.log('Getting D...');
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Hello D!');
        }, 1000);
    });
}

async function getAll() {
    await a();
    await b();
    await c();
    await d();
    console.log('Done');
}