【问题标题】:Chaining promises in ES6/Typescript在 ES6/Typescript 中链接承诺
【发布时间】:2017-02-05 19:30:11
【问题描述】:

我需要链接 promise 以发出多个 GET 请求并组合数据,然后再在其他地方使用它。我很难解决这两个承诺。在尝试使用 .json() 之前,我尝试返回两个承诺的数组,但这也不起作用。

activate() {

    // data is from http://jsonplaceholder.typicode.com/photos and
    // since there is not a photos2/ endpoint this is conceptual and 
    // represents batch importng
    return Promise.all([
        this.http.fetch('photos'),
        this.http.fetch('photos2')
    ]).then(responses => {

        console.log(responses); // see block of code below this for output

        // how can I combine the two promises here so I can resolve them with 'then' below?
        return responses[0].json(); // can return one response
        // return responses; //  doesn't work

    }).then(data => {
        console.log(data);
        this.photos = data;

    }).catch(err => {
        console.log(err);
    });
}

console.log(responses) 的输出; :

[Response, Response]
0: Response
body: (...) // readablebytestream
bodyUsed : false
headers : Headers
ok : true
status : 200
statusText : "OK"
type : "cors"
url : "http://jsonplaceholder.typicode.com/photos"
__proto__ : Object
1 : Response
 ....etc

谢谢!

【问题讨论】:

  • console.log(responses[0].json(), responses[1].json())。有什么承诺吗?我怀疑json() 是异步的。
  • @Ryan 不必如此。它可以是传递给下一个承诺的值。
  • 是的,它记录了两个用正确数据解析的 Promise。我不能正确地将事物作为我的数据变量传递。如果我通过responses(注释掉)然后尝试在下一个承诺中以相同的方式(.json)访问它们,我会得到两个未定义值的未决承诺。
  • return Promise.all(responses.map(r => r.json()));,然后呢?
  • @bmb242 删除了我的答案... Ryan 的建议正是您所需要的。获得结果对象后,将它们合并到适合您的用例并为下一个 Promise 处理程序返回合并的对象。

标签: javascript typescript ecmascript-6 es6-promise fetch-api


【解决方案1】:

您可以从响应中提取所需的 json 数据,并通过映射它们将它们发送到下一个 Promise:

activate() {
    return Promise.all([
        this.http.fetch('photos'),
        this.http.fetch('photos2')
    ]).then(responses => {

        // this will send the actual json data 
        // you want to the next chained promise
        return responses.map(response => response.json())

    }).then(data => {

        // data is now an array of the the json objects 
        // you are trying to get from the requests
        console.log(data);
        this.photos = data;

    }).catch(err => {
        console.log(err);
    });
}

第一个承诺(Promise.all)将发送请求。在第一个.then 中,responses 将是一个响应数组。由于您需要响应中的实际数据,因此您可以通过responses map 获取您想要的数据。由于这会返回,它将被传递到下一个.then。此时,data 将是一个数组,其中包含您想要从响应中获取的数据。

然后由您决定要如何处理这些数据。如果你想将它们“组合”成一个对象,那么有很多方法可以解决它(我可能会使用数组 reduce 函数,但这取决于数据的结构和你想要从中得到什么。

【讨论】:

  • 非常感谢!当你详细解释事情时,我决定选择这个答案
【解决方案2】:

你似乎在寻找

return Promise.all([responses[0].json(), responses[1].json()]);

或者干脆做

this.photos = Promise.all([
    this.http.fetch('photos').then(response => response.json()),
    this.http.fetch('photos2').then(response => response.json())
])

【讨论】:

  • 是的,这正是我想要的!非常感谢@Bergi,非常感谢!!!
猜你喜欢
  • 1970-01-01
  • 2016-06-13
  • 2016-04-02
  • 2017-06-03
  • 2018-12-04
  • 2016-08-06
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多