2017-08-12 72 views
-2

我知道承諾是我的問題的答案,但需要幫助在我的情況下如何使用。nodejs等待被調用的函數http請求完成之前從被調用者返回

我的代碼是:

... 

invoke: (abc) => { 
    module.exports.getData(); 
    return; 
}, 

getData:() => { 
    request(options, function(err, res, body) { 
    if (res && (res.statusCode === 200 || res.statusCode === 201)) { 
     logger.info("vacation balacne response:" + body); 
    } 
    }); 
}, 

... 

所以在我目前的狀況,invoke方法不會等待的getData完成。我需要從getData中的調用返回響應數據,並在invoke方法中使用它。請指教。

+0

你不能讓'getData()'等待結果(因爲Javascript異步操作的方式)並且你不能直接從'getData()'返回結果,因爲它是異步的並且函數返回LONG之前異步結果可用。相反,您可以返回一個承諾,然後調用者可以使用promise上的'.then()'方法來檢索結果。我已經標記了這個重複的答案向你展示瞭如何做到這一點,並且還有數百篇關於如何「促成」某些事情的其他文章,以使其返回一個承諾。 – jfriend00

+0

你如何做到這一點?示例plz – Vik

+0

有一篇關於如何在[你被標記爲重複的問題的接受答案](https://stackoverflow.com/a/14220323/816620)中做到這一點的LONG論文。去閱讀並研究所有這些。鏈接到你的問題標題下方。標記重複的地方在於,我們不打算再次複製關於此主題的另一個問題中所寫的全部內容。在這裏每天都會發布幾十種這樣的問題,因爲它是爲大多數剛剛接觸node.js的人開發的新方法。必須學習。 – jfriend00

回答

0

不知道有關語法,但你可以調用方法裏面的getData功能同步 -

invoke: (abc) => { 
     module.exports.getData(function(err,result){ 
     if(err) // do something 
     else // do something 
     return; 
     }); 
    }, 
    getData:(callback) => { 
    request(options, function(err, res, body) { 
      if (res && (res.statusCode === 200 || res.statusCode === 201)) { 
        logger.info("vacation balacne response:" + body); 
        return callback(null,body); 
       } 
      else return callback(err,null); 
      }); 

} 

希望它能幫助!

0

當然不會,它是一個異步功能。最簡單的辦法是做回調擺脫getDatainvoke,以便調用可以通過它進入的getData,然後的getData可以叫做「無論你需要有持續下去。」一旦數據可用:

var Thing = { 
    .... 

    invoke: (andThenDoThis) => { 
    Thing.getData(andThenDoThis); 
    }, 

    getData: (andThenDoThis) => { 
    request(options, function(err, res, body) { 
     if (res && (res.statusCode === 200 || res.statusCode === 201)) { 
     logger.info("vacation balacne response:" + body); 
     } 

     // THIS IS WHERE YOUR CODE WILL NOW CONTINUE: 
     if (andThenDoThis) { 
     andThenDoThis(err, res, body) 
     } 
    }); 
    }, 
    ... 
}; 

雖然當然這是愚蠢的,因爲只是定義對象與this引用來代替:

class Thing { 
    constructor(options) { 
    this.options = options; 
    } 

    invoke() { 
    this.getData((err, res, body) => { 
     this.handleData(err, res, body); 
    }); 
    } 

    getData(andThenDoThis) { 
    request(this.options, (err, res, body) => { 
     this.handleData(err, res, body) 
    }); 
    } 

    handleData(err, res, body) { 
    // do some `err` checking 
    // do some `res` checking 
    // do some `body` parsing 
    // do whatever else 
    if (this.options.forwardData) { 
     this.options.forwardData(...); 
    } 
    } 

    ... 
} 

然後就是做這些事情之一:

// make a thing: 
let thing = new Thing({ 
    ..., 
    forwardData: (data) => { 
    // do whatever with your data. 
    }, 
    ... 
}); 

// and then invoke whatever it is you actually needed to do. 
thing.invoke(); 

// code here keeps running, but that's fine, because now you're 
// using "code triggers only when, and where, it needs to".