Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何创建带有承诺的初始化函数?_Javascript_Promise_Q - Fatal编程技术网

Javascript 如何创建带有承诺的初始化函数?

Javascript 如何创建带有承诺的初始化函数?,javascript,promise,q,Javascript,Promise,Q,我需要一个初始化函数,一个模块只调用一次。此函数是一个承诺,由执行函数调用。如果两次调用execute,则第二个必须等待初始化,然后继续执行 我写了这段代码,但是第二次调用execute总是在等待,并且永远不会返回。我错过了什么 var initialized = false; var initializing = false; var initializationPromise; var init = function () { initializing = true; re

我需要一个初始化函数,一个模块只调用一次。此函数是一个承诺,由执行函数调用。如果两次调用execute,则第二个必须等待初始化,然后继续执行

我写了这段代码,但是第二次调用execute总是在等待,并且永远不会返回。我错过了什么

var initialized = false;
var initializing = false;
var initializationPromise;

var init = function () {
    initializing = true;
    return q.promise(function (resolve) {
        // simulate initialization
        setTimeout(function () {
            // initialized
            initialized = true;
            resolve();
        }, 1000);
    }).fin(function () {
        initializing = false;
    });
};
var execute = function () {
    return q.promise(function (resolve, reject, notify) {
        if (initialized) {
            // already initialized
            resolve();
        } else {
            if (!initializing) {
                // initializing
                initializationPromise = init().then(function () {
                    // simulate execution
                    setTimeout(function () {
                        resolve();
                    }, 1000);
                }, function (reason) {
                    reject(reason);
                });
            } else {
                // Wait : initializing in progress
                return initializationPromise;
            }
        }

    });
};

execute().then(function () {
    // This is executed
});
execute().then(function () {
    // This is never executed
});
这是不对的。这并不等待任何事情,它只是从
q.promise
构造函数中退出,不做任何事情。此外,你似乎还雇佣了一名员工

你应该做的是

var initialisationPromise = null;
function isInitialised() {
    return initialisationPromise != null && initialisationPromise.isFulfilled();
}
function isInitialising() {
    return initialisationPromise != null && initialisationPromise.isPending();
}

function init() {
    // init can be called as often as necessary, and returns when it's done
    if (initialisationPromise == null) { // do the test here!
        // this part runs only once
        initialisationPromise = q.promise(function (resolve) {
            // simulate initialization
            setTimeout(function () {
                // initialized
                resolve();
            }, 1000);
        });
    }
    return initialisationPromise;
}
function execute() {
    return init().then(function () {
        return q.promise(function(resolve, reject, notify) {
            // simulate execution
            setTimeout(function () {
                resolve();
            }, 1000);
        });
    });
}
这是不对的。这并不等待任何事情,它只是从
q.promise
构造函数中退出,不做任何事情。此外,你似乎还雇佣了一名员工

你应该做的是

var initialisationPromise = null;
function isInitialised() {
    return initialisationPromise != null && initialisationPromise.isFulfilled();
}
function isInitialising() {
    return initialisationPromise != null && initialisationPromise.isPending();
}

function init() {
    // init can be called as often as necessary, and returns when it's done
    if (initialisationPromise == null) { // do the test here!
        // this part runs only once
        initialisationPromise = q.promise(function (resolve) {
            // simulate initialization
            setTimeout(function () {
                // initialized
                resolve();
            }, 1000);
        });
    }
    return initialisationPromise;
}
function execute() {
    return init().then(function () {
        return q.promise(function(resolve, reject, notify) {
            // simulate execution
            setTimeout(function () {
                resolve();
            }, 1000);
        });
    });
}

已解析/已拒绝的承诺将保持其状态(已解析或已拒绝状态),因此您只能使用它运行一次初始化代码。为此,
init()
函数应该返回始终相同的承诺,而不是每次都创建它

因此,我们在
initializationDeferred
方法之外创建一个延迟对象(
initializationDeferred
),并使用
initializationDeferred
在每次调用
init()
方法时返回相同的承诺。我们还需要检查
init()
之前是否已经执行过,如果在以前的调用中已经执行过,则使用共享变量
initializationStarted
跳过
setTimeout

现在,在
execute
中,您可以确保只有在初始化
init()
方法时才会调用
then()
的oncompleted回调

var initializationDeferred=Q.defer();//在这里创建延迟对象,以便它对所有init()调用都是通用的
var initializationStarted=false;
var init=函数(){
如果(!initializationStarted){
initializationStarted=true;
setTimeout(函数(){
//初始化
log('Init timeout fired!');
initializationDeferred.resolve(true);//解析与延迟对象关联的承诺
}, 1000);
}
return initializationDeferred.promise;//返回与延迟对象关联的承诺
};
var execute=function(){
返回init()。然后(函数(已初始化){
//在这里,您的模块被初始化,您可以做任何您想做的事情
//此处“initialized”的值始终为“true”
log('Execute:initialized?',initialized);
});
};
execute().then(function()){
//这是执行
log('executefirst invocation');
});
execute().then(function()){
//这也被执行了
log('executesecondinvocation');
});

已解决/已拒绝的承诺将保持其状态(已解决或已拒绝的状态),因此您只能使用它运行一次初始化代码。为此,
init()
函数应该返回始终相同的承诺,而不是每次都创建它

因此,我们在
initializationDeferred
方法之外创建一个延迟对象(
initializationDeferred
),并使用
initializationDeferred
在每次调用
init()
方法时返回相同的承诺。我们还需要检查
init()
之前是否已经执行过,如果在以前的调用中已经执行过,则使用共享变量
initializationStarted
跳过
setTimeout

现在,在
execute
中,您可以确保只有在初始化
init()
方法时才会调用
then()
的oncompleted回调

var initializationDeferred=Q.defer();//在这里创建延迟对象,以便它对所有init()调用都是通用的
var initializationStarted=false;
var init=函数(){
如果(!initializationStarted){
initializationStarted=true;
setTimeout(函数(){
//初始化
log('Init timeout fired!');
initializationDeferred.resolve(true);//解析与延迟对象关联的承诺
}, 1000);
}
return initializationDeferred.promise;//返回与延迟对象关联的承诺
};
var execute=function(){
返回init()。然后(函数(已初始化){
//在这里,您的模块被初始化,您可以做任何您想做的事情
//此处“initialized”的值始终为“true”
log('Execute:initialized?',initialized);
});
};
execute().then(function()){
//这是执行
log('executefirst invocation');
});
execute().then(function()){
//这也被执行了
log('executesecondinvocation');
});

通过“此函数是一个承诺”您的意思是“此函数返回一个承诺”?通过“此函数是一个承诺”您的意思是“此函数返回一个承诺”?不,这将运行初始化两次我已更新了代码。检查控制台消息,您将看到初始化代码只执行了一次。是的,
initializationStarted
已丢失,感谢您的编辑。否,这将运行初始化两次我已更新代码。检查控制台消息,您将看到初始化代码只执行了一次。是的,
initializationStarted
已丢失,感谢您的编辑。我们在逻辑中使用的
IsInitialized
IsInitialized
在哪里?@Ultrablendz我们没有,但似乎OP对它们有一些用处。如果不需要状态,您可以安全地忽略它们。我们在逻辑中使用
IsInitialized
IsInitialized
的位置在哪里?@Ultrablendz我们没有,但OP似乎对它们有一些用处。如果不需要状态,可以安全地忽略它们。