将promise的返回值传递给许多功能的最佳方法

时间:2018-08-04 18:35:44

标签: javascript asynchronous promise async-await

让一个函数返回一个promise:

async function foo() {
  return await new Promise((res, rej) => {
    fetch('https://jsonplaceholder.typicode.com/todos/1')
          .then(res => res.json())
          .then(data => res(data))
          .catch(err => rej(err))
  })
}

为了重用返回的数据,我可以这样考虑:

(async function() {
    data = await foo().catch(err => console.log('err: ', err))
    fnc1(data)
    fnc2(data)
    ...
    fncn(data)
})();

或类似的东西

foo().then(data => {
                fnc1(data)
                fnc2(data)
                ...
                fncn(data)
              }
        )

因此,我总是必须回到我的代码中,找到该函数或回调以获取Promise返回的数据,并将我想要的任何新函数包含在适当的块中。

我想知道是否有任何更聪明的方法可以在javascript中获得相同的结果。 我知道以下内容将无法正常工作:

var dataFromPromise
foo().then(data => dataFromPromise = data)
console.log(dataFromPromise) //undefined if called before foo runs

2 个答案:

答案 0 :(得分:1)

将诺言存储一次:

 const dataPromise = foo();

然后,当您需要调用使用该函数的函数时:

 dataPromise.then(fnc1)

或在async function内:

 fnc1(await dataPromise)

答案 1 :(得分:1)

不要在承诺中包装承诺

fetch已返回一个Promise,因此无需将其包装到另一个Promise中。代替:

async function foo() {
  return await new Promise((res, rej) => {
    fetch('https://jsonplaceholder.typicode.com/todos/1')
          .then(res => res.json())
          .then(data => res(data))
  })
}

要做:

function foo(){
  return fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(res => res.json())
  .then(data => res(data))
  .catch(err => rej(err))
}

重用承诺

一旦有了一个Promise,无论它是待处理,被拒绝还是被兑现,您都可以一次又一次地重用它,并且如果它得到解决,它将始终提供返回的值。所以代替:

foo().then(data => {
    fnc1(data)
    fnc2(data)
    ...
    fncn(data)
  }
)

您可以这样做:

const myPromise = foo();

myPromise.then(data => fnc1(data));

// some code

myPromise.then(data => fnc2(data));

// more code

myPromise.then(data => fnc3(data));

您可以确定fnc1和其他人在诺言解决之前不会接到电话。

现在,这肯定是好的,但不能解决所有所有相关问题,并且这种方法仍然会发生很多坏事。解决所有可能的方式来处理和重用Promise对于SO答案来说太宽泛了。

关于该主题的一个很好的资源是:

http://2ality.com/2017/08/promise-callback-data-flow.html