蓝鸟递归承诺没有得到解决/履行

时间:2015-03-10 07:49:21

标签: javascript node.js promise bluebird

使用BlueBird承诺,我试图将getCredentials变成一个可以作为getCredentials.then(function() { do this and that } );的承诺。不确定我做错了什么,因为当我在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', 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;

2 个答案:

答案 0 :(得分:1)

getCredentials()getPassword()在完成后无法解决他们的承诺。他们永远不会得到解决。

我从代码中假设您还希望使用writeToFile承诺链接getPassword承诺,因此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);
                });
        });
    });
}

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

答案 1 :(得分:1)

  

不确定我做错了什么,因为当我在writeToFile中解析时,承诺不算作已解决/已完成

嗯,您从writeToFile 返回的承诺是已履行 但是从getPasswordgetCredentials返回的承诺永远不会 - 您不是在调用他们的 resolve函数。 Promise构造函数不会神奇地知道在其中使用的异步回调,或 将在其中创建的承诺。

你不能return来自异步回调的任何东西,你通过调用另一个(回调)函数来发出结果信号的唯一方法。在Promise构造函数的解析器内部,这将是resolvereject回调。

您可能希望查看my rules for promise development。我们几乎从不使用Promise构造函数,只能在尽可能低的promisify使用{{3}}。在你的情况下,那将是

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构造函数:

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;
相关问题