这是我的第一个 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 是完全有效的。他们都会看到相同的分辨率值(或拒绝原因)。如果在消费者调用 then
或 catch
之前 Promise 已经得到解决,那么这根本不是问题。
请注意,您对 Promise 的使用缺少拒绝处理程序。使用 Promise 的规则之一是:要么处理错误(通过 catch
或 then
的第二个参数),要么传递 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/