【问题标题】:How to get Primitive Array from ES6 Promises如何从 ES6 Promises 中获取原始数组
【发布时间】:2017-08-02 03:15:53
【问题描述】:

我正在尝试使用 ES6 Promise 和 Fetch API 将 glsl 脚本加载为字符串。我认为我有一个非常优雅的解决方案来获取顶点和片段着色器并使用 twgl.js 创建一个新的 programInfo

Promise.all([fetch(vert_url),fetch(frag_url))])
       .then((responses) => responses.map((response) => response.text()))
       .then((sources) => this.programInfo = twgl.createProgramInfo(gl, sources));

问题在于 response.text() 似乎返回的是 Promise 而不是原始字符串。在 twgl.createProgramInfo() 内部,它通过映射运行源,然后尝试对结果运行 indexOf。

function createProgramInfo(gl, shaderSources, ...) {
    ...
    shaderSources = shaderSources.map(function (source) {
      // Lets assume if there is no \n it's an id
      if (source.indexOf("\n") < 0) {
      ...

Chrome 在最后一行抛出一个 javascript 错误:

Uncaught (in promise) TypeError: source.indexOf is not a function

我似乎无法弄清楚如何将sources 变成真正的字符串。有人知道如何让它工作吗?

注意:这实际上是在一个使用 create-react-app 创建的 React 应用程序中,这意味着 webpack 和 babel 被用于从 jsx 转译。 p>

【问题讨论】:

  • @4castle 也许考虑把你的评论变成一个答案,这样这个帖子就可以关闭了
  • @4castle 的答案是正确的,但从实现的角度来看,为什么不将thens 组合起来,因为第一个没有做任何异步行为?
  • @Damon 如果他们不使用两个 then 调用,他们最终会得到嵌套的回调,而这对于 Promise 来说是不必要的。
  • @4castle 怎么会这样?您可以在第一个then 中将映射传递给createProgramInfo,类似于this.programInfo = twgl.createProgramInfo(gl, responses.map(_=&gt;_.text())),因为承诺同步映射没有意义。
  • @Damon 根据 OP,.text() 返回一个承诺,而不是他们的函数期望的实际字符串,因此必须有另一个 .then 等待这些承诺。

标签: javascript reactjs es6-promise twgl.js


【解决方案1】:

为了将promise数组转换成数组promise,使用Promise.all

Promise.all([fetch(vert_url), fetch(frag_url)])
       .then(responses => Promise.all(responses.map(response => response.text())))
       .then(sources => this.programInfo = twgl.createProgramInfo(gl, sources));

Promise#then 将评估您在来自Promise.all 的回调中返回的承诺,并将对.then 的下一次调用评估为源数组,这是您的代码所期望的。


有了像Bluebird 这样的promise 库,您可以使用Promise.map 以使其更具可读性。

Promise.all([fetch(vert_url), fetch(frag_url)])
       .map(response => response.text())
       .then(sources => this.programInfo = twgl.createProgramInfo(gl, sources));

【讨论】:

  • 很好,从未听说过这种技术,但也可以使用arguments 并且不需要额外的承诺?似乎有点像滥用承诺。
  • @JuanMendes 也许您应该发布自己的答案?这段代码非常简单(它不是什么特殊技术),但是如果您知道另一种方式,请分享。
猜你喜欢
  • 2018-04-05
  • 2015-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-29
相关资源
最近更新 更多