Javascript 使用模块化JS正确处理承诺,我是否可以多次引用同一个Promise.then()?

Javascript 使用模块化JS正确处理承诺,我是否可以多次引用同一个Promise.then()?,javascript,webpack,promise,babeljs,es6-modules,Javascript,Webpack,Promise,Babeljs,Es6 Modules,这是我的第一个堆栈溢出问题,也是我第一次构建一个供公众使用的应用程序。所以,如果这个问题有很多具体的答案,请原谅我。再说一次,我可能做错了 我有一个SPA,它使用ES6模块和网页包,并使用Babel进行传输 在初始化程序的某些部分之前,我希望能够检索一些配置/依赖项 我正在使用jQuery.ajax,它包含在一个承诺中 我有一个生活模块。我不确定这是一种好的做法 iLife.modular.promise.js export default (function(){ // console

这是我的第一个堆栈溢出问题,也是我第一次构建一个供公众使用的应用程序。所以,如果这个问题有很多具体的答案,请原谅我。再说一次,我可能做错了

我有一个SPA,它使用ES6模块和网页包,并使用Babel进行传输

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

我正在使用jQuery.ajax,它包含在一个承诺中

我有一个生活模块。我不确定这是一种好的做法

iLife.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
        }

    })
}())


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 }

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

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()

});
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 }
这似乎没有任何问题。然而,需要来自承诺的响应来配置随后由不同模块引用的对象的初始状态

puzzle.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()

});
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 }
当承诺得到解决时,
puzzle.js
模块将引用puzzle对象/类

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

puzzle.js
创建对象的新实例

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

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

不使用返回承诺的模块化生活可能更有效。IE使用只调用一次的函数声明/表达式

onsefly.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
        }

    })
}())


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 }

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

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

many.promises.js index.js 所有这些选项似乎都有潜力,不会使我正在构建的应用程序崩溃

我没有太多关注何时调用承诺以及它们是否是异步的。因为我使用jQuery.ajax,所以我认为它们不是真正的异步承诺

任何建议都将不胜感激

我有一个生活模块。我不确定这是一种好的做法

如果您使用的是ES2015模块,正如您所说的那样,这是不必要的。模块有自己的作用域

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

那很好,一点问题也没有。多个消费者使用相同的承诺是完全有效的。它们都将看到相同的分辨率值(或拒绝原因)。如果承诺在消费者呼叫
然后
catch
之前就已经解决了,这根本不是问题


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


关于:

import { default as modPromise } from './modular.promise.js'
尽管这样做有效,但导入默认导出的更惯用方法是:

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

欢迎来到堆栈溢出!请拿着(你得到了一个徽章!),四处看看,仔细阅读,特别是我还推荐乔恩·斯基特的。最好让你的问题尽可能简短和有针对性,同时确保问题的完整性。“注意,你对承诺的使用缺少拒绝处理程序。”-谢谢你指出这一点。我一直在读关于用承诺处理错误的文章(包括你在fetchapi上的博文),这比我最初想象的要复杂。特别是考虑到我正在ES6 Promise中包装
jQuery.ajax
。我可能会放弃jQuery(旧版本),走另一条路。我把这个承诺放在生活中,这样它就会被立即调用。我想我可以自己导出承诺以获得同样的效果。@Cloudbop-:-)是的,您可以
导出默认AjaxPromise(/*…*/)然后在任何您想使用该信息的地方:
从“/iife.modular.promise.js”导入modPromise;然后(数据=>{/*…使用数据…*/}).catch(错误=>{/*…处理存在错误的事实…*/})Crowder-感谢您的帮助。我接受了你的回答。