蓝鸟递归承诺没有得到 resolved/fulfilled

bluebird recursive promise not getting resolved/fulfilled

使用 BlueBird promises,我试图将 getCredentials 变成一个可以像 getCredentials.then(function() { do this and that } ); 一样工作的 promise。不确定我做错了什么,因为当我在 writeToFile 中解决时,promise 不算作 resolved/fullfilled.

function getPassword(user) {
    return new Promise(function(resolve, reject) {
    read({prompt: "Password: ", silent: true, replace: "*" }, function (er, pass) {
        rest.postJson(URL, payload(user, pass))
            .on('fail', httpFail)
            .on('error', conError)
            .on('success', writeToFile);
    });
    });
}

function getCredentials() {
    return new Promise(function(resolve, reject) {
    read({prompt: "Username: "}, function (er, user) {
        getPassword(user);
    });
    });
}

function writeToFile(data, response) {
     return new Promise(function(resolve, reject) {
    tokenFile = 'gulp/util/token-file.json'
    token = {
        id: data.access.token.id,
        expires: data.access.token.expires
    }
    token = JSON.stringify(token);
    fs.writeFile(tokenFile, token, function(err) {
        if (err) throw err;
        console.log("Token was successfully retrieved and written to " .cyan +
            tokenFile .cyan + "." .cyan);
    resolve();
    });
     });
}

module.exports = getCredentials;

getCredentials()getPassword() 没有兑现他们完成时的承诺。他们永远得不到解决。

我从代码中假设您还想将 getPassword 承诺与 writeToFile 承诺链接起来,这样 getPassword 直到 writeToFile 才解析。

可能看起来像这样:

function getPassword(user) {
    return new Promise(function(resolve, reject) {
        read({prompt: "Password: ", silent: true, replace: "*" }, function (er, pass) {
            rest.postJson(URL, payload(user, pass))
                .on('fail', httpFail)
                .on('error', conError)
                .on('success', function(data, response) {
                    writeToFile(data, response).then(resolve);
                });
        });
    });
}

您可能还想实现错误处理。

Not sure what I am doing wrong, because when I resolve in writeToFile the promise is not counted as resolved/fullfilled

好吧,你 return 从 writeToFile 兑现的承诺。
但是从 getPasswordgetCredentials 中 return 得到的 promise 永远不会是——你没有调用 他们的 resolve 函数。 Promise 构造函数不会神奇地知道其中使用的异步回调,或者 将在其中创建承诺。

您不能 return 异步回调中的任何内容,从那里发出结果信号的唯一方法是调用另一个(回调)函数。在 Promise 构造函数的解析器内部,这将是 resolvereject 回调。

您可能希望查看尽可能低的 my rules for promise development. We almost never use the Promise constructor, only to promisify。在你的情况下,那将是

function readAsync(options) {
    return new Promise(function(resolve, reject) {
        read(options, function (err, pass) {
            if (err) reject(err);
            else resolve(pass);
        }
    });
}
function postAsync(url, payload) {
    return new Promise(function(resolve, reject) {
        rest.postJson(url, payload)
        .on('fail', reject)
        .on('error', reject)
        .on('success', resolve);
    });
}

尽管使用 Bluebird 我们可以将第一个简化为

var readAsync = Promise.promisify(read);

和类似用途

var writeFileAsync = Promise.promisify(fs.writeFile, fs);

现在我们有了那些 promise-returning 函数,我们可以应用其余规则并将它们组合在一起,而无需再使用 Promise 构造函数:

function getPassword(user) {
    return readAsync({prompt: "Password: ", silent: true, replace: "*" })
    .then(function(pass) {
        return postAsync(URL, payload(user, pass))
    });
}

function getCredentials() {
    return readAsync({prompt: "Username: "}).then(getPassword);
}

function writeToFile(data, response) {
    var tokenFile = 'gulp/util/token-file.json';
    var token = JSON.stringify({
        id: data.access.token.id,
        expires: data.access.token.expires
    });
    return writeFileAsync(tokenFile, token).then(function() {
        console.log("Token was successfully retrieved and written to " .cyan +
                    tokenFile .cyan + "." .cyan);
    });
}

module.exports = getCredentials;