将异步方法包装到 return 一个承诺(bluebird)

Wrap async method to return a promise (bluebird)

我想在 bluebird promises 中包装一些同步函数,以便我可以将它们与其他异步方法混合使用。

我遵循了 的回答并创建了两个封装在 promise 中的方法:

var Promise = require("bluebird");

var foo1 = Promise.method(function(arg){
    console.log(arg);
    return "ret foo1";
});

var foo2 = Promise.method(function(arg){
    console.log(arg);
    return "ret foo1";
});

但是调用这些方法时

foo1.then(foo2);

我有这个例外

    TypeError: Object function () {
    var ret = new Promise(INTERNAL);
    ret._captureStackTrace();
    ret._pushContext();
    var value = tryCatch(fn).apply(this, arguments);
    var promiseCreated = ret._popContext();
    debug.checkForgottenReturns(
        value, promiseCreated, "Promise.method", ret);
    ret._resolveFromSyncValue(value);
    return ret;
} has no method 'then'

你必须这样调用 foo1()

foo1("hello").then(foo2);

foo1 是一个函数,return 是一个承诺。您必须调用它才能获得承诺 returned.

工作片段:

var foo1 = Promise.method(function(arg){
    log(arg);
    return "ret foo1";
});

var foo2 = Promise.method(function(arg){
    log(arg);
    return "ret foo1";
});

foo1("hello").then(foo2);

function log(x) {
    var div = document.createElement("div");
    div.innerHTML = x;
    document.body.appendChild(div);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.0.5/bluebird.js"></script>

您可能还想知道 foo2 不必 return 承诺,因此您不需要 Promise.method() 除非您希望能够调用它链中的第一个。常规函数可以是 .then() 处理程序。

foo1.then(foo2) 表示 'invoke the method then on foo1'。但是 foo1 没有 属性 then。但是,调用 foo1 结果确实 ,因为结果将是 Promise。

供参考,Bluebird的Promise#methodreturns一个函数:

Returns a new function that wraps the given function fn.

所以你想要做的是:

foo1('string').then(foo2)

请注意承诺 return 承诺。所以 foo2 作为一个 promise 是不必要的。

这是一个创建承诺而不是使用 promise.method 的解决方案。

此外,我还提供了一个使用函数的示例,它不是一个承诺,但表明它 return 无论如何都是一个承诺。

var Promise = require('bluebird');

var foo1 = new Promise(function(resolve){
    resolve("ret foo1");
});

var foo2 = new Promise(function(resolve){
    resolve("ret foo2");
});

function foo3(arg){
  console.log('Promises return promises');
  return arg;
}

foo1.then(foo3).then(foo2).then(function(arg){
  console.log(arg);
});