Async: 承诺支持

创建于 2015-11-13  ·  22评论  ·  资料来源: caolan/async

添加承诺支持以允许混合不同的任务:

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    function(content) {
        // Do something and return Promise
        return mongoose.models.file.create({
            name: filepath,
            content: content
        });
    }
], (err) => {
    if (err) {
        console.error(err);
    }
});
feature

最有用的评论

我认为就像有 async.asyncify 可能有一个 async.promisify 函数。

然后我可以等待 async.promisify(async.mapLimit(x,10, mapper))

所有22条评论

asyncify将采用一个同步函数,该函数返回一个 Promise 并在其已解决/拒绝的处理程序上调用回调:

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    async.asyncify(function(content) {
        // Do something and return Promise
        return mongoose.models.file.create({
            name: filepath,
            content: content
        });
    })
], (err, model) => {
    if (err) {
        console.error(err);
    }
});

但该功能没有记录......

我还有另一个想法——我们是否应该自动异步化返回承诺的函数(或适当地处理它们?)。 当传递一个 ES-whatever async函数(隐式返回一个承诺)时,异步应该做什么?

例如

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    async function(content) {
        return await mongoose.models.file.create({
            name: filepath,
            content: content
        });
    }
], (err, model) => {
    if (err) {
        console.error(err);
    }
});

就个人而言,我认为 async 应该默认异步化 promises。 我写了一些异步函数,我也必须输入 async.queue,但我不想写这个:

import {queue, asyncify} from 'async'

const run = asyncify(async function () {
  await someStuff()
})

const q = async.queue(run)
q.push('asdf')

我可以在哪里写这个

import {queue} from 'async'

async function run () {
  await someStuff()
}

const q = async.queue(run)
q.push('asdf')

添加了asyncify的文档。 将保持对自动 asyncify-ing 行为的开放。

关于这一点,我正在尝试使用相同的代码库,并为使用回调作为最后一个参数的方法使用 Promise 接口。 检查它

async.waterfall([
  function (callback) {
    callback(null, 'one', 'two')
  },
  function (arg1, arg2, callback) {
    // arg1 now equals 'one' and arg2 now equals 'two'
    callback(null, 'three')
  },
  function (arg1, callback) {
    // arg1 now equals 'three'
    callback(null, 'done')
  }
]).then(function (value) {
  console.log(value === 'done')
})

你怎么看待这件事? 我认为这很容易适应图书馆。 例如,请参阅如何让库句柄 cb 和 promise 工作

很有意思。 如果 Async 正确处理了返回 promise 的函数,那么它也可以很容易地接受 promisify-ed Async 函数。 这会起作用:

async.parallel([
  async.waterfall([
    asyncFn1,
    function (result1, next) {
      //...
    }
    asyncFn2,
    //...
  ]), // no callback!
  async.each(arr, function (item, cb) {
    //...
  })
  otherAsyncFn
], done)

结合 Async 函数会容易得多。

今天的问题是回调是可选的。 离开最后一个参数仍然执行任务。 我很想使 Async 函数自动柯里化——如果你不使用回调,它会部分应用该函数,你需要做的就是用回调调用它。 但是看到许多方法都有可选参数,而且我们正在全面转向可选回调,你不能真正做到这一点。 我们的方法是可变参数的,你不能咖喱可变参数函数。

然而,如果一个方法不使用最后的回调,它会返回一个 Promise,并且如果 Async 被设置为处理返回 Promise 的函数,这是一个有趣的组合。 一个主要问题是 Async 必须与承诺库集成——哪个? 我们是依赖global.Promise ,强制旧引擎进行 polyfill,还是使用 Bluebird 之类的东西? 此外,Async 是一种反对承诺的声明——回调接受函数的高阶函数,而不是采用 Futures 范式。 我完全赞成与 Promises 的互操作性,但我认为 Async return promises 有点超出其设计理念。

@aearly

我觉得 Promises 是一个与上一个节点版本(>=4)一致的工作流。 在这个版本中 Promises 可用,所以,我的愿景是当全局环境有 Promises 时使用 Promise 工作流。

可以添加一个小的 polyfill(检查小指承诺)但在我看来没有意义提供 polyfill。 更好地强制用户升级节点版本以使用最后一个节点功能。 真的,检查(获得 6 PR)[https://github.com/sindresorhus/got/pull/140]。 依赖在非常小的项目中是不受欢迎的,并且无处不在。

也许在异步模块化之后包含这个特性会很好,代码库将更容易适应。

但可以肯定的是,将异步与承诺对齐是完全_必须_的!

@Kikobeats :+1:

Promise 正在成为一流的异步函数。 因此,如果没有它们的完全支持,很难想象异步的必备库。

我认为它可以在没有 polyfill 的情况下实现,但具有功能检测:如果存在具有resolve方法的全局 Promise 对象,则允许。

@aearly bluebird 将浏览器兼容性添加到它的

@martinheidegger Bluebird 太大了。 它将投射 76 Kb(缩小)以简单地支持 promise 方法。

同样,在后端工作流中使用回调或承诺接口是基于节点版本的自然过程。

  • 如果您有更多时间后端(可能是 2 年或更长时间),则使用0.100.12版本,因此,您的代码以回调风格编写。
  • 如果您的后端不到 6 个月并且您使用>=4节点版本,则您可能使用了 Promise 风格。

但无论如何,你没有混合风格。

所以没有必要为支持 Promise 添加依赖项; 如果 async 在未来某一天支持 Promise,那么如果您的节点版本支持 Promise,您就可以使用它。

极端情况:_我使用的是旧节点版本,但我的后端是使用 Promise 风格编写的_。 然后您已经将 Promises 对象定义为全局或

前端的行为相同。 不需要依赖。

嗯,看起来 Promises 4-5 年前的问题仍然适用。 如果每个人都使用 node 4 或更高版本,以及支持 ES6 的现代浏览器,我们可以在适用的情况下轻松地在内部使用 promise。

问题是我们将节点 0.12 和旧版浏览器用户置之不理,要求他们进行 polyfill。 他们使用哪种 polyfill? 我们不想捆绑一个,即使是小指承诺也很重要。 此外,在标准 ES6 Promise 之外使用 Promise 的人会想要使用 bluebird 或 q 等,无论他们使用的是什么。 我不想要求使用 polyfill—— npm i -S async应该是所有人都需要做的。

Async 也是对 Promises 的一种反应——一种管理异步代码的替代方法。 开始使用 Promises 似乎是一种退步。 正确管理的回调可以和 Promise 一样强大(并且在许多情况下,速度更快,因为 Promise 具有内置的事件循环延迟)。

我完全支持与承诺的互操作,如果一个函数被传递了一个 Promise 或其他“thennable”,那么我们绝对应该利用它。 但是我认为我们应该避免在内部创建和/或返回 Promises,因为跨平台的 ES6 支持还有很长的路要走。

同意,创建或处理承诺并不便宜。 我宁愿将这样的事情视为选择加入扩展。 承诺很棒,但你不会总是想要它们

恕我直言,在将很多节点的代码迁移到 promises + co + yield 之后,我没有找到仅用于.eachLimit()直接替换。 可能,有用的案例列表比乍一看要少得多,可以用单独的包处理。

我喜欢@Kikobeats小扩展,在自述文件中推荐它可能是有意义的(/cc @aearly)。

由于我和其他用户提出的原因,我强烈反对官方支持异步承诺。

@megawac函数返回承诺的情况如何? 例如@SEAPUNK的例子。

@megawac我在promise-async 中添加了对回调样式、测试和浏览器构建的支持。 那么如果有人想使用Promise,我认为已经准备好了:+1:

@aearly ,我想这很好(所以=)但我宁愿把它留在插件中
亲自登陆

2016 年 1 月 22 日星期五下午 2:17,Kiko Beats [email protected]
写道:

@megawac https://github.com/megawac我添加了对回调样式的支持
和 promise-async 的测试
https://github.com/Kikobeats/promise-async#promise -async。 那么如果
任何人都想使用 Promise,我认为已经准备好了 [图片::+1:]


直接回复此邮件或在 GitHub 上查看
https://github.com/caolan/async/issues/956#issuecomment -174016628。

这是另一个承诺所有可用异步方法的包:
https://github.com/eladnava/koa-async

我认为就像有 async.asyncify 可能有一个 async.promisify 函数。

然后我可以等待 async.promisify(async.mapLimit(x,10, mapper))

如果您想创建拉取请求,我不会反对

2016 年 12 月 17 日星期六下午 4:57,Manoj Patel通知@github.com
写道:

我认为就像有 async.asyncify 可能有 async.promisify
功能。

然后我可以等待 async.promisify(async.mapLimit(x,10, mapper))


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/caolan/async/issues/956#issuecomment-267789633或静音
线程
https://github.com/notifications/unsubscribe-auth/ADUIEKJIDulPHAn_SeEZbiPb3t7ORGnpks5rJFqvgaJpZM4Gh1fr
.

我正在使用bluebird模块的promisifyAll方法将回调转换为承诺,以便异步方法变为:

// adds '<original-method>Async' to class 
Promise.promisifyAll(async);

function somePromise() {
    return async.parallelAsync([
        function(cb) {
            setTimeout(function(){
                cb(new Error('err'), 'foo')
            }, 1000);
        },
        function(cb) {
            setTimeout(function(){
                cb(null, 'bar')
            }, 1000);
        }
    ]);
}

somePromise().then(function(result){
    console.log('result',result);
}).catch(function(err){
    console.log('err',err);
});

JSFiddle 示例

此页面是否有帮助?
0 / 5 - 0 等级