javascript - 使用模块化 JS 正确处理 Promise,我可以多次引用同一个 Promise.then() 吗?

标签 javascript webpack promise babeljs es6-modules

这是我的第一个 Stack Overflow 问题,也是我第一次构建供公众使用的应用程序。因此,如果这个问题似乎可以用许多具体答案来解释,请原谅我。话又说回来,我可能做错了!

我有一个 SPA,它使用带有 Webpack 的 ES6 模块并使用 Babel 进行转译。

我希望能够在程序的某些部分初始化之前检索一些配置/依赖项。

我正在使用封装在 Promise 中的 jQuery.ajax。

我有一个 IIFE 模块。我不确定这是否是好的做法。

iife.modular.promise.js

export default (function(){
    // console.log('iife.modular.promise.js is invoked when app is parsed');

    function AjaxPromise(options) {

        // console.log ('Promise invoked, get response');

        return new Promise(function (resolve, reject) {
            jQuery.ajax(options).done(resolve).fail(reject);
        });

    }

    return AjaxPromise({
        url: YOUR_URL,
        type: 'post',
        data: {
          action: get_some_data
        }

    })
}())


然后我可以在另一个模块中引用它。

index.js

import { default as modPromise } from './iife.modular.promise.js'
import { startApp } from './startApp.js'

modPromise.then( (response)=>{
  // return response data and do stuff.
  console.log(response)
  // EG
  // {
  //   success: true,
  //   data: "Hello World!"   
  // }

  // run application
  startApp()

});

这似乎工作没有任何问题。但是,需要来自 Promise 的响应来配置对象的初始状态,然后由不同的模块引用这些对象。

puzzle.js

import { default as modPromise } from'./iife.modular.promise.js'

class Puzzle {
    constructor(name, level, [args]) {
        this.name = name;
        this.level = level;
        this.puzzleSpec = [args]
    }

    isInit() {
        return `class initialised`;
    }
}

// closure
var puzzleInit;

modPromise.then( (response)=>{
  // my response data actually evaluates to an array
  let data = JSON.parse(response.data)
  // instantiate class.
  puzzleInit = new Puzzle ( ...data )
});

export { puzzleInit }

当 Promise 被解析时,puzzle.js 模块将引用 Puzzle 对象/类。

这就是我困惑的地方。我引用同一个 Promise 两次,并在两个单独的模块中调用 .then() 方法。

puzzle.js 创建对象的新实例。

index.js 用作控制流。在实例化 puzzle.js 之前不要运行该应用。

它似乎没有给出任何引用错误。考虑到 iife.modular.promise.js 只被调用一次并返回一个可能被多次引用的 Promise 对象,我不明白为什么这会成为一个问题。

不使用返回 Promise 的模块化 IIFE 可能会更有效。 IE 使用仅调用一次的函数声明/表达式。

onTheFly.modular.promise.js

function onTheFly(){

    function AjaxPromise(options) {

        return new Promise(function (resolve, reject) {
            jQuery.ajax(options).done(resolve).fail(reject);
        });

    }

    return AjaxPromise({
        url: YOUR_URL,
        type: 'post',
        data: {
          action: get_some_data
        }

    })
}

export { onTheFly }

但是,每次在模块中调用 onTheFlyPromise() 时,都会发出新的 Promise/请求。这意味着为了在不同模块之间共享response.data,数据必须存储在专用模块中。

解决此问题的一种可能方法是使用 Promise.all()

many.promises.js

const manyPromise = function(args){

    return Promise.all(args);
}

export { manyPromise };

index.js

import { default as modPromise } from './modular.promise.js'
import { onTheFlyPromise } from './onTheFly.modular.promise.js'
// Promise All
import { manyPromise } from './manyPromise.js'

import { startApp } from './startApp.js'

const multiplePromises = manyPromise(modPromise, onTheFlyPromise() ); 

multiplePromises.then( (response)=>{
  // return response data from all promises and do stuff.
  console.log(response)

// EG [{ },{ }]

  // run application
  startApp()

});

所有这些选项似乎都有潜力,并且不会使我正在构建的应用程序崩溃。

我不太关注 Promise 何时被调用以及它们是否是异步的。我假设因为我使用的是 jQuery.ajax,所以它们不是真正的异步 Promise?

如有任何建议,我们将不胜感激。

最佳答案

I have a module that is an IIFE. I am not sure this is good practice.

如果您像您所说的那样使用 ES2015 模块,则没有必要。模块有自己的作用域。

This is where I am perturbed. I am referencing the same Promise twice and invoking the .then() method in two separate modules.

完全没问题,没有任何问题。对于多个消费者使用相同的 promise 是完全有效的。他们都会看到相同的分辨率值(或拒绝原因)。如果在消费者调用 thencatch 之前 Promise 已经得到解决,那么这根本不是问题。

请注意,您对 Promise 的使用缺少拒绝处理程序。使用 Promise 的规则之一是:要么处理错误(通过 catchthen 的第二个参数),要么传递 then 的结果处理错误。

<小时/>

注意事项:

import { default as modPromise } from './modular.promise.js'

虽然这可行,但导入默认导出的更惯用的方法是:

import modPromise from './modular.promise.js';

关于javascript - 使用模块化 JS 正确处理 Promise,我可以多次引用同一个 Promise.then() 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56026619/

相关文章:

javascript - 如何使用 JavaScript 将 html 页面内容保存在 .txt 文件中?

reactjs - Webpack 热模块重新加载器无法与 React 无状态组件一起使用

javascript - 使用 Jasmine 测试嵌套的 promise

ecmascript-6 - Webpack - 作为依赖的外部 JS/JSON 文件

javascript - Css 类名不适用于 React 组件

mysql - Select Exists 在 mysql 中总是返回 true

javascript - Angularjs 从 Controller 范围内的 promise 返回数据

javascript - 在列表之间绘制箭头

javascript - 如何获得textarea中的最大数字?

javascript - Angular 4 中 Promise 的实现错误