Promise不解析node.js

时间:2017-01-07 12:09:56

标签: javascript node.js promise es6-promise

我试图通过sendRequest函数解决一些承诺,但它不起作用。

例如,如果我在所有时间唤起sendRequest function 4次,我可以看到在控制台中打印的日志然后转到resolve(data)。但是,只有4次中的1次,该程序进入sendRequest.then()

以下是该文件的完整代码。

变化name.js

var sendRequest = function(fileName){
    return new Promise(function (resolve,reject) {
        httpRequest(fileName).then(function (data) {
            try{
                if(.....){
                    if(.....){
                        var lastIndex = ....;}
                    if(.....){
                        var lastIndex = ....;}
                    str = fileName.substring(0, lastIndex);
                    if(.........){
                        sendRequest(str);}
                    else{
                        reject("this is the end");}
                    }
                else{
                    console.log("end result" + JSON.stringify(data,null,4));
                    resolve(data);
                    //===== THIS RESOLVE DOES NOT WORK WHILE THE LOG PRINTS THE DATA =====//
                    }
                }
            catch(e){
                resolve(data);
                }
        }).catch(function (err) {
            reject(err);
        });
    });
};

server.js

此文件从sendRequest调用change-name.js函数,然后在此处应用then函数。

fs.readdir(path,(err,files)=>{
    if(err){
        console.log(err);
        return;
        }
    for(i=0;i<files.length;i++){
        sendRequest(files[i]).then(function (data) {
        console.log(data + "\n");
    }).catch(function(err){
        console.log("end Error is " + err + "\n");
    });
    console.log(files);
  }
});

github链接是&#34; https://github.com/abhikulshrestha22/movierator&#34;。

任何帮助将不胜感激。谢谢

1 个答案:

答案 0 :(得分:4)

问题是你的一个分支再次调用sendRequest 而不是解析或拒绝,但是然后没有使用递归调用返回的promise,所以您为外部调用创建的承诺永远不会被解决。内在的(这就是你在控制台中看到消息的原因),但由于没有任何东西正在使用这个承诺,你得不到你期望的结果。

您的代码中根本不需要new PromisehttpRequest已经为您提供了一个承诺,并且您的then处理程序会创建一个承诺(如果您返回一个值)。所以sendRequest应该只返回在then的承诺上调用httpRequest的结果,并在then回调中,返回值来解析新的承诺,或者拒绝。在您再次调用sendRequest的分支中,返回它返回的承诺;然后then创建的那个将根据该承诺解决/拒绝:

var sendRequest = function(fileName) {
    return httpRequest(fileName).then(function(data) {
        if (condition1) {
            if (condition2) {
                var lastIndex = something;
            }
            if (condition3) {
                var lastIndex = somethingElse;
            }
            str = fileName.substring(0, lastIndex);
            if (condition4) {
                return sendRequest(str);
            }
            else {
                throw new Error("this is the end");
            }
        }
        else {
            console.log("end result" + JSON.stringify(data, null, 4));
            return data;
        }
    });
};

以下是httpRequest返回1-10的随机数的实例,如果该数字小于8,则再次调用sendRequest;在放弃之前它会尝试三次:

function httpRequest() {
    return new Promise(function(resolve) {
        setTimeout(function() {
            resolve(Math.floor(Math.random() * 10) + 1);
        }, 500);
    });
}
var sendRequest = function(fileName, retries) {
    if (typeof retries !== "number") {
        retries = 3;
    }
    return httpRequest(fileName).then(function(data) {
        console.log("`then` got: " + data);
        if (data > 7) {
            console.log("It's > 7, yay! We're done");
            return data;
        }
        console.log("It's <= 7g");
        if (--retries === 0) {
            console.log("Out of retries, rejecting");
            throw new Error("out of retries");
        }
        console.log("retrying (" + retries + ")");
        return sendRequest(fileName, retries);
    });
};

document.getElementById("btn").addEventListener("click", function() {
    var btn = this;

    btn.disabled = true;
    console.log("Sending request");
    sendRequest("foo")
        .then(function(data) {
            console.log("Request complete: " + data);
        })
        .catch(function(err) {
            console.log("Request failed: " + err);
            // Because we don't throw here, it converts the rejection into a resolution...
        })
        .then(function() {
            // ...which makes this kind of like a "finally"
            btn.disabled = false;
        });
}, false);
<input type="button" id="btn" value="Start">